Django 2.0中自定义表单验证器未触发问题求助
Hey Richard, let's work through why your clean_postcode validation method isn't running—there are a couple of straightforward fixes needed:
1. Your view isn't triggering form validation
Right now, your index view only creates an empty form instance. Django runs validation (including custom clean_* methods) only when you call form.is_valid(), which you're not doing. You need to handle POST submissions in your view to trigger this process.
2. Typos in your form's clean method
There are two small errors in your clean_postcode function that break it even if validation was triggered:
- You used
self.clean_datainstead of the correct attribute nameself.cleaned_data - You tried to return
data, a variable that wasn't defined (you should return the processedpostcodeinstead)
Fixed Code Examples
Corrected forms.py:
from django import forms from django.utils.translation import gettext_lazy as _ class PostcodeForm(forms.Form): postcode = forms.CharField(required=True, widget=forms.TextInput( attrs={ 'placeholder': "enter a postcode", } )) def clean_postcode(self): # Fixed: Use cleaned_data instead of clean_data postcode = self.cleaned_data.get('postcode', '') print('clean_postcode', postcode) if postcode != 'something': raise forms.ValidationError(_("Please enter a valid postcode"), code='invalid') # Fixed: Return the processed postcode variable return postcode
Corrected views.py:
from django.shortcuts import render from .forms import PostcodeForm def index(request): if request.method == 'POST': # Initialize form with POST submission data form = PostcodeForm(request.POST) # This line triggers all validation, including clean_postcode if form.is_valid(): # Access validated data after successful check valid_postcode = form.cleaned_data['postcode'] # Add your post-validation logic here (e.g., redirect, save data) else: # Empty form for GET requests form = PostcodeForm() context = { 'form': form } return render(request, 'your_template_name.html', context)
Quick Template Check
Make sure your template uses POST method and includes a CSRF token (required for Django form submissions):
<form method="POST"> {% csrf_token %} {{ form.as_p }} <button type="submit">Submit</button> </form>
With these changes, when a user submits the form, Django will run form.is_valid() and your clean_postcode method will execute as expected.
内容的提问来源于stack exchange,提问作者Richard

