我有一个样本表格:
class AdminDiscountForm(ModelForm):
class Meta:
model = Discount
exclude = ('company',)
它指向的模型是:
class Discount(models.Model):
class Meta:
verbose_name=_('Discount')
verbose_name_plural=_('Discounts')
unique_together = ('company','type')
company = models.ForeignKey(Company)
type = models.CharField(max_length=5, choices=DISCOUNT_CHOICES)
discount = models.DecimalField(max_digits=7, decimal_places=2, verbose_name=_('Discount'))
表单排除了“公司”字段,因为用户已使用UI选择了该字段。
我打算做一个:
company = blah
if form.is_valid():
obj = form.save(commit=False)
obj.company = company
obj.save()
问题是'company'和'type'的组合应该是唯一的(因此'unique_together')。这是在数据库中强制执行的,所以django并不关心。 我需要扩展此表单的clean()方法以检查唯一性:
def clean(self):
cleaned_data = self.cleaned_data
# check for uniqueness of 'company' and 'type'
这里的问题是'公司'不在那里,因为它被排除在外。 在这种情况下,提出表单验证错误的最佳方法是什么?
- 编辑 这仅适用于添加折扣条目。 没有初始实例。
答案 0 :(得分:11)
Jammon的方法是我使用的方法。扩展一下(使用你的例子):
models.py
class Discount(models.Model):
class Meta:
verbose_name=_('Discount')
verbose_name_plural=_('Discounts')
unique_together = ('company','type')
company = models.ForeignKey(Company)
type = models.CharField(max_length=5, choices=DISCOUNT_CHOICES)
discount = models.DecimalField(max_digits=7, decimal_places=2, verbose_name=_('Discount'))
forms.py
class AdminDiscountForm(ModelForm):
class Meta:
model = Discount
exclude = ('company',)
views.py
def add_discount(request, company_id=None):
company = get_object_or_404(Company, company_id)
discount=Discount(company=company)
if request.method == 'post':
form = AdminDiscountForm(request.POST, instance=discount)
if form.is_valid():
form.save()
return HttpResponse('Success')
else:
form = AdminDiscountForm(instance=company)
context = { 'company':company,
'form':form,}
return render_to_response('add-discount.html', context,
context_instance=RequestContext(request))
这可以通过创建折扣模型的实例,然后将表单绑定到此实例来实现。此实例不会保存到您的数据库,但用于绑定表单。此绑定表单具有绑定实例的公司值。然后将其发送到您的模板以供用户填写。当用户提交此表单并验证表单时,模型验证检查将检查Meta中定义的唯一的唯一性。
请参阅Model Validation Docs
和overriding clean for ModelForms
修改强>
你可以做一些事情来捕捉非独特的一起进入尝试。
在form.is_valid()中,您可以使用以下完整性错误:
if request.method == 'post':
form = AdminDiscountForm(request.POST, instance=discount)
if form.is_valid():
try:
form.save()
return HttpResponse('Success')
except IntegrityError:
form._errors["company"] = "some message"
form._errors["type"] = "some message"
else:
...
在模型表单的clean方法中使用self.instance来检查唯一性。
答案 1 :(得分:2)
你可以试试这个:
discount = Discount(company = blah)
form = AdminDiscountForm(request.POST, instance=discount)
if form.is_valid():
discount = form.save()
而docs说:默认情况下,clean()方法会验证标记为... unique_together