You need to enable JavaScript to run this app. Django表单触发ValidationError立即终止:验证码错误不执行clean_address方法
优惠活动
大模型
产品
解决方案
定价
更多

Django表单触发ValidationError立即终止:验证码错误不执行clean_address方法

问题原因

Django表单默认会按字段定义顺序执行所有字段的校验逻辑(包括clean_<fieldname>自定义校验),就算前面的字段校验失败也不会中途终止,所以验证码校验失败后依然会执行clean_address里的逻辑。

解决方法

重写表单的全局clean方法,把address的自定义校验逻辑放到全局校验的最后,前置字段有错误时直接终止后续逻辑:

from django import forms
from captcha.fields import ReCaptchaField

from .models import Server, Category
from .utils.status_manager import ServerStatus


class AddServerForm(forms.ModelForm):
    captcha = ReCaptchaField()
    categories = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(attrs={'class': 'checkbox'}),
                                           error_messages={
                                               'required': 'You need to select server type'
                                           },
                                           choices=[(c.pk, c.name) for c in Category.objects.all()]
                                           )

    def clean(self):
        cleaned_data = super().clean()
        # 前置字段校验失败直接终止后续逻辑
        if self.errors:
            return cleaned_data
        
        # 原clean_address的校验逻辑移到此处
        address = cleaned_data.get('address')
        if address:
            if Server.objects.filter(address=address).exists():
                self.add_error('address', "Server is on the list")
                return cleaned_data
            if not ServerStatus(address).is_server_on():
                self.add_error('address', "Server is offline")
                return cleaned_data
        return cleaned_data

    class Meta:
        model = Server
        fields = ['address']

说明

  • 全局clean方法执行前,已经完成所有前置字段的基础校验(包括recaptcha校验、categories必填校验),只要self.errors中存在错误就直接返回,不会触发address的自定义校验
  • 用add_error方法绑定字段错误,和原clean_address抛出错误的前端展示效果完全一致,不会影响原有错误提示逻辑

内容的提问来源于stack exchange,提问作者ivall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 14:45:01