You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我的Django表单没有触发ValidationError校验错误?

解决方案

1. 修正 forms.py 代码

Django 表单的跨字段校验建议使用标准的clean()方法,该方法会在你调用表单的is_valid()时自动触发,无需手动调用。同时你原有代码存在字段名引用错误的问题,修正后代码如下:

from django import forms
from django.core.validators import MinValueValidator
from django.utils.translation import gettext_lazy as _

class PlayerForm(forms.Form):
    # 积分上限
    points_high = forms.IntegerField(
        validators=[MinValueValidator(0)],
        min_value=0, 
        label='积分上限',
        required=False,
        widget=forms.NumberInput(
            attrs={'id': 'pointsHigh',
                   'class': "form-control"}
        )
    )
    # 积分下限
    points_low = forms.IntegerField(
        validators=[MinValueValidator(0)], 
        min_value=0, 
        label='积分下限',
        required=False,
        widget=forms.NumberInput(
            attrs={'id': 'pointsLow',
                   'class': "form-control"}
        )
    )

    def clean(self):
        """跨字段校验上下限大小"""
        cleaned_data = super().clean()
        points_low = cleaned_data.get('points_low')
        points_high = cleaned_data.get('points_high')

        if points_low and points_high:
            if points_low > points_high:
                raise forms.ValidationError(_("下限值不能高于上限值!"))
        return cleaned_data

注意:原有代码中widget的name、href、value属性无需手动指定,Django会自动生成,冗余属性已删除

2. 修正 views.py 逻辑

原视图没有触发表单校验逻辑,直接从GET请求取参数查询,修正后逻辑为:先将请求参数传入表单,校验通过后再执行查询,校验失败则将错误信息返回前端:

def player_points(request):
    # 将GET参数传入表单
    players_form = PlayerForm(request.GET)
    players = []
    # 只有请求带参数且表单校验通过时才查询数据
    if request.GET and players_form.is_valid():
        points_high = players_form.cleaned_data['points_high']
        points_low = players_form.cleaned_data['points_low']
        stat_kwargs = {}
        if points_high:
            stat_kwargs['points__lte'] = points_high
        if points_low:
            stat_kwargs['points__gte'] = points_low
        players = Players.objects.filter(**stat_kwargs)
    
    context = {
        'players': players,
        'form': players_form
    }
    return render(request, 'nba/players.html', context)

注意:原有过滤条件的键需要是字符串格式,且要兼容参数为空的情况,避免无效过滤

3. 前端模板添加错误提示

在你的nba/players.html模板中,表单渲染位置添加如下代码,即可显示校验错误提示:

<!-- 显示跨字段校验错误 -->
{% if form.non_field_errors %}
    <div class="alert alert-danger">
        {% for error in form.non_field_errors %}
            <p>{{ error }}</p>
        {% endfor %}
    </div>
{% endif %}

<!-- 表单渲染示例 -->
<form method="get">
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary">查询</button>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:06:02