使用ValidationError且不跳转页面的表单验证技术咨询
Hey there! Let's fix this issue step by step. The problem with your current code is that the ValidationError raised in clean_smth() doesn't get caught by that try-except block in your view—Django handles form validation errors internally by storing them in the form's errors attribute when you call is_valid(), not by throwing an uncaught exception.
Fixed View Code
def your_view_name(request): if request.method == 'POST': form = Form(request.POST) if form.is_valid(): # Important: Note that `forms.Form` (not ModelForm) doesn't have a `save()` method! # Handle your cleaned data manually here, e.g.: cleaned_data = form.cleaned_data # Run your business logic (like saving to database) return redirect('this_current_page') # Only redirect if validation passes else: form = Form() # Initialize empty form for GET requests # Return the same page with the form (and errors if validation failed) return render(request, 'your_template.html', {'form': form})
Key Fixes Explained
- Removed the unnecessary
try-exceptblock: It can't catch form validation errors because Django traps them in the form instance itself. - When validation fails (your
problem_conditionis true),form.is_valid()returnsFalse, and the error message you defined gets stored inform.smth.errors. - Instead of redirecting, we render the same template with the form instance containing errors—this keeps the user on the current page while showing validation feedback.
Template Setup (Show Errors Without Redirect)
Update your template to display the validation errors inline. You can use Django's built-in form rendering or customize it:
<form method="post"> {% csrf_token %} <!-- Option 1: Auto-render form with errors --> {{ form.as_p }} <!-- Option 2: Custom field rendering for better control --> <div class="form-field"> {{ form.smth.label_tag }} {{ form.smth }} {% if form.smth.errors %} <div class="error-message"> {% for error in form.smth.errors %} {{ error }} {% endfor %} </div> {% endif %} </div> <button type="submit">Submit</button> </form>
Quick Note
If you intended to use a ModelForm (which has a save() method), make sure your form inherits from forms.ModelForm instead of forms.Form. For a standard Form, you'll need to handle the cleaned data directly as shown in the view code.
内容的提问来源于stack exchange,提问作者Ken - Enough about Monica

