Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django views Django 1.3 CreateView/ModelForm:unique_与表单中排除的一个字段一起验证_Django Views_Django Forms_Django 1.3 - Fatal编程技术网

Django views Django 1.3 CreateView/ModelForm:unique_与表单中排除的一个字段一起验证

Django views Django 1.3 CreateView/ModelForm:unique_与表单中排除的一个字段一起验证,django-views,django-forms,django-1.3,Django Views,Django Forms,Django 1.3,我正在寻找这个常见问题的简单答案。到目前为止,我找到的答案忽略了我们初学者的关键点 我有一个应用程序,几乎每个模型都有一个用户外键,并且有一个唯一的约束,其中一个字段总是“User” 例如: class SubscriberList(models.Model): user = models.ForeignKey(User) name = models.CharField(max_length=70) date_created = models.DateTimeField(auto_now_ad

我正在寻找这个常见问题的简单答案。到目前为止,我找到的答案忽略了我们初学者的关键点

我有一个应用程序,几乎每个模型都有一个用户外键,并且有一个唯一的约束,其中一个字段总是“User”

例如:

class SubscriberList(models.Model):

user = models.ForeignKey(User)
name = models.CharField(max_length=70)
date_created = models.DateTimeField(auto_now_add=True)

class Meta:
    unique_together = (
        ('user', 'name',),
        )   

def __unicode__(self):
    return self.name
SubscriberList总是由登录用户创建的,因此在创建订阅者列表的表单中,我排除了User字段,并在保存表单时给它一个值self.request.User,如下所示:

class SubscriberListCreateView(AuthCreateView):
model = SubscriberList
template_name = "forms/app.html"
form_class = SubscriberListForm
success_url = "/app/lists/"

def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.user = self.request.user
    return super(SubscriberListCreateView, self).form_valid(form) 
以下是随附的表格:

class SubscriberListForm(ModelForm):
class Meta:
    model = SubscriberList
    exclude = ('user')
有了这段代码,有效数据就可以了。当我提交不唯一的数据时,我从数据库中得到一个完整性错误。原因对我来说很清楚-Django不会一起验证unique_,因为“user”字段被排除在外

如何更改现有代码,仍然使用CreateView,以便提交的非唯一数据一起引发表单验证错误,而不是数据库中的完整性错误。

从以下位置的文档中获取:

如果您计划自己处理验证错误,或者从ModelForm中排除了需要验证的字段,则只需要调用模型的full_clean()方法

从以下文档中获取:

混合FormMixin的视图必须提供form_valid()和form_invalid()的实现

这意味着,为了查看错误(与表单无关),您需要实现自己的表单_invalid,在那里添加特殊的错误消息,然后返回它

因此,在对象上运行full_clean()会引发unique_together错误,因此您的代码可能如下所示:

def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.user = self.request.user
    # validate unique_together constraint
    try:
        self.object.full_clean()
    except ValidationError:
        # here you can return the same view with error messages
        # e.g.
        return self.form_invalid(form)
    return super(SubscriberListCreateView, self).form_valid(form)

def form_invalid(self, form):
    # using messages
    # from django.contrib import messages
    # messages.error('You already have a list with that name')
    # or adding a custom error
    from django.forms.util import ErrorList
    form._errors["name"] = ErrorList([u"You already have a list with that name"])
    return super(SubscriberListCreateView, self).form_invalid(form)

HTH

Yehonatan的示例让我达到了目的,但我必须从form\u valid的ValidationError中调用消息,而不是单独的form\u invalid函数

这项工作:

class SubscriberCreateView(AuthCreateView):
型号=订户
template_name=“forms/app.html”
form_class=订阅格式
success_url=“/app/subscribers/”
def表单_有效(自身、表单):
self.object=form.save(commit=False)
self.object.user=self.request.user
尝试:
self.object.full_clean()
除ValidationError外:
#raise ValidationError(“不行,您以前使用过此名称!”)
#返回自我。表单_无效(表单)
从django.forms.util导入错误列表
表单。_errors[“email”]=错误列表([u“您已经有一封名为man的电子邮件。”)
返回super(SubscriberCreateView,self)。表单_无效(表单)
返回super(SubscriberCreateView,self)。form_有效(form)

添加另一个对noobs来说可能更容易的示例

forms.py

class GroupItemForm(ModelForm):
    def form_valid(self):
        self.object = self.save(commit=False)
        try:
            self.object.full_clean()
        except ValidationError:
            # here you can return the same view with error messages
            # e.g. field level error or...
            self._errors["sku"] = self.error_class([u"You already have an email with that name."])
            # ... form level error
            self.errors['__all__'] = self.error_class(["error msg"]
            return False
        return True
views.py

def add_stock_item_detail(request, item_id, form_class=GroupItemForm, template_name="myapp/mytemplate.html"):
    item = get_object_or_404(Item, pk=item_id)
    product = Product(item=item)
    if request.method == 'POST':
        form = form_class(request.POST, instance=product)
        if form.is_valid() and form.form_valid():
            form.save()
            return HttpResponseRedirect('someurl')
    else:
        form = form_class(instance=product)

    ctx.update({
        "form" : form,
     })

    return render_to_response(template_name, RequestContext(request, ctx))

对AuthCreateView的引用是什么?试着理解为什么super会被叫到面纱上。我以前没见过。干杯