想象一下,我们正在建立一个民意调查网站,就像Django tutorial中的那个。
有两种型号。一个问题,一个选择。每个选项都有一个问题的外键。我们希望确保每个问题至少有两个选择,但不超过5个选择。
在创建问题时,您还可以同时创建选项。因此,两个对象将同时保存。在保存时,如何验证Question对象是否有2-5个与之关系的选项?
由于你不能在未保存的对象上设置关系,我不确定应该如何实现。我想到的第一个解决方案是在问题对象上设置一个pre_save
钩子,但正如我刚才说的那样,对象尚未保存,因此选择对象不能与它有关系。
我想到的第二个解决方案是设置post_save
挂钩,保存问题,然后保存选项,然后检查问题是否有2-5个选项。这个解决方案看起来非常糟糕,我确信有更好的方法。
你怎么能得到这种功能?
如果它有所不同我在使用PostgreSQL 9.4的Django 1.8上。
答案 0 :(得分:1)
您可以通过覆盖可以继承的formset上的clean
来执行此类验证:
from django.forms.models import BaseInlineFormSet
class RequiredFormSet(BaseInlineFormSet):
def clean(self):
for error in self.errors:
# If any errors exist, return
if error:
return
completed_formsets = 0
for cleaned_data in self.cleaned_data:
# only count the form if it's not being deleted
if cleaned_data and not cleaned_data.get('DELETE', False):
completed_formsets += 1
if completed_formsets < 2 or completed_formsets > 5:
raise forms.ValidationError("You must enter between "
"2 and 5 {}".format(self.model._meta.verbose_name))
如果您之后需要使用发布数据调用API,则可以覆盖保存,或者在您的项目中执行以下任何操作。
表单的最小/最大数量可能来自设置,或者在实例化formset时传入,而不是在此示例中对其进行硬编码。