使用POST提交非Django模板表单时遇CSRF Token错误的解决咨询
Alright, let's tackle that CSRF token error you're getting when submitting a non-Django-template form via POST. I've looked at your view code, and here's how to fix this properly (plus some context so you understand why it's happening):
Why this error happens
Django's built-in CSRF protection middleware checks every POST request for a valid CSRF token to prevent cross-site request forgery attacks. When you use Django templates, the {% csrf_token %} tag automatically adds a hidden input with the token, but since you're not using Django templates, you have to handle this manually.
Fix 1: Properly pass the CSRF token to your form (Recommended)
This is the secure, production-ready approach. We'll update your view to expose the CSRF token, then add it to your form or request headers when submitting.
Step 1: Modify your view to return the CSRF token
Add a get method to your class-based view and use Django's get_token utility to fetch and return the token:
from django.middleware.csrf import get_token from django.http import JsonResponse, HttpResponse from django.views.generic import View class YourFormView(View): # Replace with your actual view name form_class = YourFormClass # Replace with your form class def get(self, request): # Retrieve the CSRF token from the request context csrf_token = get_token(request) # Option 1: Return as JSON (ideal for AJAX/SPA frontends) return JsonResponse({'csrf_token': csrf_token}) # Option 2: Return custom HTML with embedded token (if serving raw HTML) # html_content = f''' # <form method="POST" enctype="multipart/form-data"> # <input type="hidden" name="csrfmiddlewaretoken" value="{csrf_token}"> # <!-- Add your form fields here --> # <input type="email" name="email" required> # <input type="file" name="file"> # <button type="submit">Submit</button> # </form> # ''' # return HttpResponse(html_content) def post(self, request): # Your existing post logic remains unchanged form = self.form_class(request.POST or None, request.FILES or None) if form.is_valid(): email = form.cleaned_data.get('email') user = authenticate(email=email) if user is None: form.save() message = 'Saved Successfully' return HttpResponse(message) else: message = 'User Exists' return HttpResponse(message) else: message = 'Invalid form data' return HttpResponse(message)
Step 2: Include the token in your POST request
- Plain HTML form: Add a hidden input field with the token value you retrieved from the
getrequest. - AJAX (fetch/axios): Add the token to the request headers as
X-CSRFToken:// Example with fetch API fetch('/your-view-url/', { method: 'POST', headers: { 'X-CSRFToken': 'YOUR_CSRF_TOKEN_FROM_GET_REQUEST', }, body: new FormData(document.getElementById('your-form-id')) }) // Example with axios axios.post('/your-view-url/', formData, { headers: { 'X-CSRFToken': 'YOUR_CSRF_TOKEN_FROM_GET_REQUEST' } })
Fix 2: Disable CSRF protection (NOT recommended for production)
If you're just testing and need a quick workaround (never use this in production), you can exempt the view from CSRF checks:
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class YourFormView(View): # Your existing post method here def post(self, request): # ... same as before ...
Warning: This disables a critical security feature, so only use this for local testing or internal tools where CSRF attacks aren't a risk.
内容的提问来源于stack exchange,提问作者Ankush paul

