Django 1.3 CreateView/ModelForm:unique_together 验证,其中一个字段从表单中排除 [英] Django 1.3 CreateView/ModelForm: unique_together validation with one field excluded from form
问题描述
我正在通过示例为这个常见问题寻找一个简单的答案.到目前为止,我找到的答案忽略了我们初学者的关键点.
I am looking for a simple answer by example to this common problem. The answers I found so far leave out critical points for us beginners.
我有一个应用程序,其中几乎每个模型都有一个到用户的外键,并且有一个 unique_together 约束,其中一个字段始终是用户".
I have an app where almost every model has a ForeignKey to User, and there is a unique_together constraint, where one of the fields is always '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
订阅者列表总是由登录的用户创建,因此在创建订阅者列表的表单中,我排除了用户字段并在保存表单时为其赋予了 self.request.user 值,如下所示:
A SubscriberList is always created by a logged in User, and thus in the form to create a Subscriber List, I exclude the user field and give it a value of self.request.user when saving the form, like so:
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')
使用此代码,有效数据就可以了.当我提交not unique_together 的数据时,我从数据库中收到一个完整性错误.原因我很清楚 - Django 不验证 unique_together 因为排除了用户"字段.
With this code, valid data is fine. When I submit data that is not unique_together, I get an Integrity Error from the database. The reason is clear to me - Django doesn't validate the unique_together because the 'user' field is excluded.
如何更改我现有的代码,仍然使用 CreateView,以便提交的不是 unique_together 的数据引发表单验证错误,而不是来自数据库的完整性错误.
How do I change my existing code, still using CreateView, so that submitted data that is not unique_together throws a form validation error, and not an Integrity Error from the db.
推荐答案
Yehonatan 的例子让我明白了,但我不得不从 form_valid 的 ValidationError 中调用消息,而不是一个单独的 form_invalid 函数.
Yehonatan's example got me there, but I had to call the messages from within the ValidationError of form_valid, rather than a separate form_invalid function.
这有效:
class SubscriberCreateView(AuthCreateView):
model = Subscriber
template_name = "forms/app.html"
form_class = SubscriberForm
success_url = "/app/subscribers/"
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
try:
self.object.full_clean()
except ValidationError:
#raise ValidationError("No can do, you have used this name before!")
#return self.form_invalid(form)
from django.forms.util import ErrorList
form._errors["email"] = ErrorList([u"You already have an email with that name man."])
return super(SubscriberCreateView, self).form_invalid(form)
return super(SubscriberCreateView, self).form_valid(form)
这篇关于Django 1.3 CreateView/ModelForm:unique_together 验证,其中一个字段从表单中排除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!