【问题标题】:Validating objects in Django with multiple forms使用多种形式验证 Django 中的对象
【发布时间】:2010-11-08 19:33:09
【问题描述】:

使用this example。假装两种形式都有日期字段。您将如何编写自定义清理以进行验证以比较两个日期?我在底部添加了一个示例 clean,它在轮询时返回一个关键错误。

模型和形式

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField()
    target_date= models.DataTimeField()

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    target_date= models.DataTimeField()
    votes = models.IntegerField(default=0)
To start, we’ll need forms for each model.

from django import forms
from mysite.polls.models import Poll, Choice

class PollForm(forms.ModelForm):
    class Meta:
        model = Poll

class ChoiceForm(forms.ModelForm):
    class Meta:
        model = Choice
        exclude = ('poll',)

观看次数

from mysite.polls.models import Poll, Choice
from mysite.polls.forms import PollForm, ChoiceForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def add_poll(request):
    if request.method == "POST":
        pform = PollForm(request.POST, instance=Poll())
        cforms = [ChoiceForm(request.POST, prefix=str(x), instance=Choice()) for x in range(0,3)]
        if pform.is_valid() and all([cf.is_valid() for cf in cforms]):
            new_poll = pform.save()
            for cf in cforms:
                new_choice = cf.save(commit=False)
                new_choice.poll = new_poll
                new_choice.save()
            return HttpResponseRedirect('/polls/add/')
    else:
        pform = PollForm(instance=Poll())
        cforms = [ChoiceForm(prefix=str(x), instance=Choice()) for x in range(0,3)]
    return render_to_response('add_poll.html', {'poll_form': pform, 'choice_forms': cforms})

在返回 poll 的关键错误的表单上运行示例清理。

def clean(self):
        if any(self.errors):
            raise forms.ValidationError("")
        data = self.cleaned_data
        choiceDate = data["target_date"]
        pollDate = data["poll"]    ##--- The key error happens here
        if choiceDate > pollDate.target_date:
            raise forms.ValidationError("Your dates do not match")
        return data

【问题讨论】:

    标签: django validation forms


    【解决方案1】:

    pollDate = data["poll"] ##--- The key error happens here

    这是因为表单没有名为 poll 的字段,因为您在表单定义中明确排除了它。我不知道你给出的清洁是在PollForm 还是ChoiceForm,但两者都没有poll 字段。

    【讨论】:

    • 正确,但我使用以下代码设置值。这是错误的方法吗? - 对于 cforms 中的 cf:new_choice = cf.save(commit=False) new_choice.poll = new_poll new_choice.save()
    • 是的,但是您在 is_valid() 调用了 clean() 之后设置了该值,并且 clean() 仍在尝试访问表单实例中不存在的字段。 .
    • 没错,实现这一目标的正确方法是什么?我知道出了什么问题,但还没有找到一种方法来重写它以使其正常工作。
    • 您不能在表单之间进行交叉验证。验证发生在他们的清洁方法中。您可以做的是,在视图中测试您从cleaned_data 中获得的内容,然后对其采取相应措施/不采取相应措施,并使用消息框架显示适当的错误消息。
    • 知道了,我想是时候深入研究内置的 django 管理站点,看看他们如何处理同样的事情了。感谢您的帮助。
    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    相关资源
    最近更新 更多