Django类视图分页中获取POST参数实现Accept/Reject功能
Solution: Handling Accept/Reject POST Requests in Django Class-Based Pagination View
Hey there! Let's fix this step by step. The main issues with your current setup are that you're using GET requests (via <a> tags) for actions that modify data (Accept/Reject), and your ListView isn't set up to handle POST submissions. Here's how to adjust everything:
Step 1: Update the Class View to Handle POST
Modify your DemoView2 to override the post method, which will process the Accept/Reject actions and redirect to the next page.
# views.py from django.views.generic import ListView from django.shortcuts import redirect class DemoView2(ListView): model = MandateTable template_name = 'demo2.html' context_object_name = 'pg' paginate_by = 1 # Add ordering to ensure consistent pagination (critical for large datasets!) queryset = MandateTable.objects.all().order_by('id')[:5] # Test with 5 objects def post(self, request, *args, **kwargs): # Get the current page's single object (since paginate_by=1) page_context = self.get_context_data() current_mandate = page_context['page_obj'].object_list[0] # Handle Accept/Reject actions if 'btn-accept' in request.POST: # Update your database field(s) here (adjust to your actual field names) current_mandate.status = 'accepted' current_mandate.save() elif 'btn-reject' in request.POST: current_mandate.status = 'rejected' current_mandate.save() # Redirect to next page or the demo URL if no pages left page_obj = page_context['page_obj'] if page_obj.has_next(): return redirect(f"{request.path}?page={page_obj.next_page_number()}") else: return redirect('demo')
Key notes here:
- We use
get_context_data()to access the current page's object list - Always order your queryset (e.g., by
id) to avoid inconsistent pagination with large datasets - We redirect after processing the POST request (PRG pattern: Post/Redirect/Get) to prevent duplicate submissions
Step 2: Fix the Template to Use POST Forms
Replace your button/link setup with a proper form that submits POST data, including the required CSRF token.
<!-- demo2.html --> {% for mandates in pg %} <p>{{ mandates.FIELD_1 }}</p> <p>{{ mandates.FIELD_2 }}</p> <p>{{ mandates.FIELD_3 }}</p> <p>{{ mandates.FIELD_4 }}</p> <p>{{ mandates.FIELD_5 }}</p> {% endfor %} {% if is_paginated %} <form method="POST"> {% csrf_token %} <!-- Required for Django CSRF protection --> <button type="submit" name="btn-accept" class="btn btn-success btn-lg"> Accept </button> <button type="submit" name="btn-reject" class="btn btn-danger btn-lg"> Reject </button> </form> {% endif %}
Why this works:
- The form submits POST data directly to the same view
- Each button has a unique
nameattribute, which we check in the view to determine the action - No need for links inside buttons anymore—we handle the redirect in the view logic
Step 3: Optional Enhancements
- Add error handling: Wrap the
save()calls in a try/except block if you need to handle database errors - Add feedback: Use Django's
messagesframework to show success/error messages to the user after submission - For very large datasets: Consider using
paginator.get_page()instead of relying on context data for extra robustness
内容的提问来源于stack exchange,提问作者moonwalker7
相关产品推荐
相关产品推荐

