在不渲染的情况下强制执行表单字段验证和显示错误?

Enforce form field validation & display error without render?

我是 django 的新手,所以非常感谢详细的回答。我对模型中任何新创建的 Bottle 对象实施 capacity 限制,如下所示:

class Bottle(models.Model):
    name = models.CharField(max_length=150, blank=False, default="")
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name="bottles")
    vintage = models.IntegerField('vintage', choices=YEAR_CHOICES, default=datetime.datetime.now().year)
    capacity = models.IntegerField(default=750,
                                   validators=[MaxValueValidator(2000, message="Must be less than 2000")
                                    ,MinValueValidator(50, message="Must be more than 50")])

我的 BottleForm 看起来像这样:

class BottleForm(ModelForm):

    class Meta:
        model = Bottle
        fields = '__all__'

我的观点(基于on this answer的表单验证逻辑):

def index(request):
    args = {}

    user = request.user
    object = Bottle.objects.filter(brand__business__owner_id=user.id).all(). \
    values('brand__name', 'name', 'capacity', 'vintage').annotate(Count('brand')).order_by('brand__count')

    args['object'] = object

    if request.method == "POST":
        form = BottleForm(request.POST)

        if form.is_valid():
            bottle = form.save(commit=False)
            bottle.save()
            return redirect('index')

    else:
        form = BottleForm()
    args['form'] = form
    return render(request, template_name="index.pug", context=args)

还有我的模板(pug 格式),像这样:

            form(class="form-horizontal")(method="post" action=".")
                | {% csrf_token %}
                for field in da_form
                    div(class="form-group")
                        label(class="col-lg-3 col-md-3 col-sm-3 control-label") {{field.label_tag}}
                        div(class="col-lg-9 col-md-9 col-sm-9")
                            | {{ field|add_class:"form-control" }}
                input(class="btn btn-primary")(type="submit" value="submit")

在修改我的代码和浏览 SO 几个小时后,我通过将 {{ form.errors }} 添加到我的模板来设法显示错误,但这只会在页面已经重新加载并且非常丑陋的形式:see here.

我想要的是在不重新加载页面的情况下利用 django 的内置弹出错误消息 (see example on default non-empty field),从用户体验的角度来看,这要好得多。

这不是 Django 消息。这是 HTML5 验证消息,由您的浏览器直接强制执行。 Django 简单地将输入字段输出为具有 max 属性的类型数字:

<input type="number" name="capacity" max="750">

我不确定你的(可怕的)哈巴狗模板是否妨碍了你,或者是否只是 Django 在你使用验证器时没有传递这些参数。您可能需要重新定义表单中的字段,指定最大值和最小值:

class BottleForm(ModelForm):
    capacity = forms.IntegerField(initial=750, max_value=2000, min_value=250)

(请注意,无论如何,在每个字段旁边执行 {{ field.errors }} 比仅在顶部执行 {{ form.errors }} 显示效果更好。)