Django表单验证取决于表单集中的数据
我有以下代码:Django表单验证取决于表单集中的数据,django,validation,django-forms,django-admin,Django,Validation,Django Forms,Django Admin,我有以下代码: from django import forms from django.core.exceptions import ValidationError class MyAdminForm(forms.ModelForm): class Meta: model = MyModel def clean(self): cleaned_data = self.cleaned_data max_num_items = cl
from django import forms
from django.core.exceptions import ValidationError
class MyAdminForm(forms.ModelForm):
class Meta:
model = MyModel
def clean(self):
cleaned_data = self.cleaned_data
max_num_items = cleaned_data['max_num_items']
inline_items = cleaned_data.get('inlineitem_set', [])
if len(inline_items) < 2:
raise ValidationError('There must be at least 2 valid inline items')
if max_num_items > len(inline_items):
raise ValidationError('The maximum number of items must match the number of inline items there are')
return cleaned_data
来自django导入表单的
从django.core.exceptions导入ValidationError
类MyAdminForm(forms.ModelForm):
类元:
model=MyModel
def清洁(自清洁):
已清理的\u数据=自清理的\u数据
max_num_items=已清理的_数据['max_num_items']
inline\u items=cleanned\u data.get('inlineitem\u set',[])
如果len(内联项)<2:
raise ValidationError('必须至少有2个有效的内联项')
如果最大数量项目>长度(内联项目):
raise ValidationError('最大项数必须与存在的内联项数匹配')
返回已清除的数据
我想我可以从cleaned_data
(通过使用cleaned_data['inlineitem_set']
)访问表单集,但事实似乎并非如此
我的问题是:
clean
方法中访问表单集的“父”表单我刚刚为自己的项目解决了这个问题。正如您在第二个问题中所建议的,任何需要访问父表单的内联表单集验证都需要位于
BaseInlineFormset
子类的clean
方法中
令人高兴的是,在调用内联表单集的clean
之前,父表单的实例被创建(或者从数据库中检索,如果您正在修改而不是创建它),并且它在那里作为self.instance
可用
from django.core.exceptions import ValidationError
class InlineFormset(forms.models.BaseInlineFormSet):
def clean(self):
try:
forms = [f for f in self.forms
if f.cleaned_data
# This next line filters out inline objects that did exist
# but will be deleted if we let this form validate --
# obviously we don't want to count those if our goal is to
# enforce a min or max number of related objects.
and not f.cleaned_data.get('DELETE', False)]
if self.instance.parent_foo == 'bar':
if len(forms) == 0:
raise ValidationError(""" If the parent object's 'foo' is
'bar' then it needs at least one related object! """)
except AttributeError:
pass
class InlineAdmin(admin.TabularInline):
model = ParentModel.inlineobjects.through
formset = InlineFormset
这里的try-except模式是为了防止出现AttributeError
的极端情况,我自己也没有看到过这种情况,但当我们尝试访问表单(在self.forms
中)的cleaned_data
属性时,这种情况显然会出现,但无法验证。这是我从你那里学到的
(注意:我的项目仍然在Django 1.3上;没有在1.4中尝试过)从Django 1.8开始,管理员调用
clean()
方法时,InlineFormset
的实例成员仍然填充。非常感谢。我在Django 1.9中做了一些非常类似的事情,它工作得很好。我要添加的一件事是在覆盖的clean函数的顶部添加一个super(InlineFormset,self)。clean()
允许您访问表单集中每个表单上的cleaned\u数据。很抱歉,我无法对该问题进行投票,但我无法这样做,因为该问题已得到回答,但答案尚未被接受。