diff --git a/examples/bootstrap4/app.py b/examples/bootstrap4/app.py
index cb08a91..193f3b7 100644
--- a/examples/bootstrap4/app.py
+++ b/examples/bootstrap4/app.py
@@ -271,10 +271,32 @@ def edit_message(message_id):
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
+ # Get current page from referrer or request args
+ current_page = request.args.get('page', 1, type=int)
+ if request.referrer and 'page=' in request.referrer:
+ # Extract page number from referrer URL
+ import re
+ page_match = re.search(r'[?&]page=(\d+)', request.referrer)
+ if page_match:
+ current_page = int(page_match.group(1))
+
+ # Delete the message
db.session.delete(message)
db.session.commit()
- return f'Message {message_id} has been deleted. Return to table.'
- return f'Message {message_id} did not exist and could therefore not be deleted. Return to table.'
+
+ # Calculate total remaining messages and pages
+ total_messages = Message.query.count()
+ per_page = 10 # Same as used in test_table route
+ total_pages = max(1, (total_messages + per_page - 1) // per_page) # At least page 1
+
+ # Determine which page to redirect to
+ redirect_page = min(current_page, total_pages)
+
+ flash(f'Message {message_id} has been deleted.', 'success')
+ return redirect(url_for('test_table', page=redirect_page))
+ else:
+ flash(f'Message {message_id} did not exist and could therefore not be deleted.', 'warning')
+ return redirect(url_for('test_table'))
@app.route('/table//like')
diff --git a/examples/bootstrap5/app.py b/examples/bootstrap5/app.py
index 0abe6d2..ec2633a 100644
--- a/examples/bootstrap5/app.py
+++ b/examples/bootstrap5/app.py
@@ -295,10 +295,32 @@ def edit_message(message_id):
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
+ # Get current page from referrer or request args
+ current_page = request.args.get('page', 1, type=int)
+ if request.referrer and 'page=' in request.referrer:
+ # Extract page number from referrer URL
+ import re
+ page_match = re.search(r'[?&]page=(\d+)', request.referrer)
+ if page_match:
+ current_page = int(page_match.group(1))
+
+ # Delete the message
db.session.delete(message)
db.session.commit()
- return f'Message {message_id} has been deleted. Return to table.'
- return f'Message {message_id} did not exist and could therefore not be deleted. Return to table.'
+
+ # Calculate total remaining messages and pages
+ total_messages = Message.query.count()
+ per_page = 10 # Same as used in test_table route
+ total_pages = max(1, (total_messages + per_page - 1) // per_page) # At least page 1
+
+ # Determine which page to redirect to
+ redirect_page = min(current_page, total_pages)
+
+ flash(f'Message {message_id} has been deleted.', 'success')
+ return redirect(url_for('test_table', page=redirect_page))
+ else:
+ flash(f'Message {message_id} did not exist and could therefore not be deleted.', 'warning')
+ return redirect(url_for('test_table'))
@app.route('/table//like')
diff --git a/tests/test_bootstrap4/test_render_pagination.py b/tests/test_bootstrap4/test_render_pagination.py
index e853584..24548fb 100644
--- a/tests/test_bootstrap4/test_render_pagination.py
+++ b/tests/test_bootstrap4/test_render_pagination.py
@@ -1,4 +1,4 @@
-from flask import render_template_string, request
+from flask import render_template_string, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
@@ -36,3 +36,108 @@ def test():
assert '1' in data
assert '2 (current)' in data
assert '10' in data
+
+
+def test_pagination_after_delete(app, client): # noqa: C901
+ """Test that pagination works correctly after deleting items."""
+ db = SQLAlchemy(app)
+
+ class Message(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ text = db.Column(db.String(100))
+
+ @app.route('/table')
+ def test_table():
+ page = request.args.get('page', 1, type=int)
+ pagination = Message.query.paginate(page=page, per_page=10)
+ messages = pagination.items
+ return render_template_string('''
+ Page {{ pagination.page }} of {{ pagination.pages }}
+ Total: {{ pagination.total }}
+ Messages: {{ messages|length }}
+ ''', pagination=pagination, messages=messages)
+
+ @app.route('/table//delete', methods=['POST'])
+ def delete_message(message_id):
+ message = Message.query.get(message_id)
+ if message:
+ # Get current page from request args or referrer
+ current_page = request.args.get('page', 1, type=int)
+ if request.referrer and 'page=' in request.referrer:
+ import re
+ page_match = re.search(r'[?&]page=(\d+)', request.referrer)
+ if page_match:
+ current_page = int(page_match.group(1))
+
+ # Delete the message
+ db.session.delete(message)
+ db.session.commit()
+
+ # Calculate total remaining messages and pages
+ total_messages = Message.query.count()
+ per_page = 10
+ total_pages = (total_messages + per_page - 1) // per_page if total_messages > 0 else 1
+
+ # Determine which page to redirect to
+ redirect_page = current_page
+ if total_pages == 0 or total_messages == 0:
+ redirect_page = 1
+ elif current_page > total_pages:
+ redirect_page = total_pages
+
+ flash(f'Message {message_id} has been deleted.', 'success')
+ return redirect(url_for('test_table', page=redirect_page))
+ else:
+ flash(f'Message {message_id} did not exist.', 'warning')
+ return redirect(url_for('test_table'))
+
+ with app.app_context():
+ # Test Case 1: Delete from middle page - should stay on same page
+ db.drop_all()
+ db.create_all()
+ for i in range(25): # Create 25 messages (3 pages of 10 each, 5 on last page)
+ msg = Message(text=f'Message {i+1}')
+ db.session.add(msg)
+ db.session.commit()
+
+ # Go to page 2 and delete a message
+ response = client.get('/table?page=2')
+ assert 'Page 2 of 3' in response.get_data(as_text=True)
+
+ # Delete message ID 15 (should be on page 2)
+ response = client.post('/table/15/delete?page=2', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 2 of 3' in data # Should still be on page 2
+ assert 'Total: 24' in data # One less message
+
+ # Test Case 2: Delete all items from last page - should redirect to previous page
+ db.drop_all()
+ db.create_all()
+ for i in range(21): # Create 21 messages (3 pages: 10, 10, 1)
+ msg = Message(text=f'Message {i+1}')
+ db.session.add(msg)
+ db.session.commit()
+
+ # Go to page 3 (last page with 1 item)
+ response = client.get('/table?page=3')
+ data = response.get_data(as_text=True)
+ assert 'Page 3 of 3' in data
+ assert 'Total: 21' in data
+
+ # Delete the only message on page 3
+ response = client.post('/table/21/delete?page=3', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 2 of 2' in data # Should redirect to page 2
+ assert 'Total: 20' in data # One less message
+
+ # Test Case 3: Delete all messages - should go to page 1
+ db.drop_all()
+ db.create_all()
+ msg = Message(text='Last message')
+ db.session.add(msg)
+ db.session.commit()
+
+ response = client.post('/table/1/delete', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 1 of' in data # Should be on page 1 (could be "Page 1 of 0" or "Page 1 of 1")
+ assert 'Total: 0' in data # No messages left
diff --git a/tests/test_bootstrap5/test_pagination.py b/tests/test_bootstrap5/test_pagination.py
index 2df3bae..ef63589 100644
--- a/tests/test_bootstrap5/test_pagination.py
+++ b/tests/test_bootstrap5/test_pagination.py
@@ -1,4 +1,4 @@
-from flask import render_template_string, request
+from flask import render_template_string, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
@@ -30,3 +30,108 @@ def test():
assert '1 (current)' not in data
assert '' in data
assert '1' in data
+
+
+def test_pagination_after_delete(app, client): # noqa: C901
+ """Test that pagination works correctly after deleting items."""
+ db = SQLAlchemy(app)
+
+ class Message(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ text = db.Column(db.String(100))
+
+ @app.route('/table')
+ def test_table():
+ page = request.args.get('page', 1, type=int)
+ pagination = Message.query.paginate(page=page, per_page=10)
+ messages = pagination.items
+ return render_template_string('''
+ Page {{ pagination.page }} of {{ pagination.pages }}
+ Total: {{ pagination.total }}
+ Messages: {{ messages|length }}
+ ''', pagination=pagination, messages=messages)
+
+ @app.route('/table//delete', methods=['POST'])
+ def delete_message(message_id):
+ message = Message.query.get(message_id)
+ if message:
+ # Get current page from request args or referrer
+ current_page = request.args.get('page', 1, type=int)
+ if request.referrer and 'page=' in request.referrer:
+ import re
+ page_match = re.search(r'[?&]page=(\d+)', request.referrer)
+ if page_match:
+ current_page = int(page_match.group(1))
+
+ # Delete the message
+ db.session.delete(message)
+ db.session.commit()
+
+ # Calculate total remaining messages and pages
+ total_messages = Message.query.count()
+ per_page = 10
+ total_pages = (total_messages + per_page - 1) // per_page if total_messages > 0 else 1
+
+ # Determine which page to redirect to
+ redirect_page = current_page
+ if total_pages == 0 or total_messages == 0:
+ redirect_page = 1
+ elif current_page > total_pages:
+ redirect_page = total_pages
+
+ flash(f'Message {message_id} has been deleted.', 'success')
+ return redirect(url_for('test_table', page=redirect_page))
+ else:
+ flash(f'Message {message_id} did not exist.', 'warning')
+ return redirect(url_for('test_table'))
+
+ with app.app_context():
+ # Test Case 1: Delete from middle page - should stay on same page
+ db.drop_all()
+ db.create_all()
+ for i in range(25): # Create 25 messages (3 pages of 10 each, 5 on last page)
+ msg = Message(text=f'Message {i+1}')
+ db.session.add(msg)
+ db.session.commit()
+
+ # Go to page 2 and delete a message
+ response = client.get('/table?page=2')
+ assert 'Page 2 of 3' in response.get_data(as_text=True)
+
+ # Delete message ID 15 (should be on page 2)
+ response = client.post('/table/15/delete?page=2', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 2 of 3' in data # Should still be on page 2
+ assert 'Total: 24' in data # One less message
+
+ # Test Case 2: Delete all items from last page - should redirect to previous page
+ db.drop_all()
+ db.create_all()
+ for i in range(21): # Create 21 messages (3 pages: 10, 10, 1)
+ msg = Message(text=f'Message {i+1}')
+ db.session.add(msg)
+ db.session.commit()
+
+ # Go to page 3 (last page with 1 item)
+ response = client.get('/table?page=3')
+ data = response.get_data(as_text=True)
+ assert 'Page 3 of 3' in data
+ assert 'Total: 21' in data
+
+ # Delete the only message on page 3
+ response = client.post('/table/21/delete?page=3', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 2 of 2' in data # Should redirect to page 2
+ assert 'Total: 20' in data # One less message
+
+ # Test Case 3: Delete all messages - should go to page 1
+ db.drop_all()
+ db.create_all()
+ msg = Message(text='Last message')
+ db.session.add(msg)
+ db.session.commit()
+
+ response = client.post('/table/1/delete', follow_redirects=True)
+ data = response.get_data(as_text=True)
+ assert 'Page 1 of' in data # Should be on page 1 (could be "Page 1 of 0" or "Page 1 of 1")
+ assert 'Total: 0' in data # No messages left