我有一个ModelForm
表单,其中有两个ModelChoiceField
输入,其中child
依赖于parent
:
parent = forms.ModelChoiceField(
widget=forms.Select(attrs=_default_attrs),
queryset=Parent.objects.all()
)
child = forms.ModelChoiceField(
widget=forms.Select(attrs=_default_attrs),
queryset=Child.objects.none()
)
我使用javascript通过API填充子项。使用上面的代码,验证失败,因为queryset
设置为none - 即没有项有效。
现在我可以将queryset
设置为Child.objects.all()
,这将解决验证问题,但由于child
有数千个项目,因此不切实际。
我知道我可以覆盖queryset
中的__init__()
,这是我尝试做的事情,但是,与我在stackoverflow中搜索的大多数情况不同,{ {1}}取决于我在检索时遇到问题的child
的值。这就是我试过的:
parent
这提出了以下内容:
def __init__(self, *args, **kwargs):
super(NewPostForm, self).__init__(*args, **kwargs)
self.fields['child'].queryset = Child.objects.filter(parent=self.fields['parent'])
探索int() argument must be a string or a number, not 'ModelChoiceField'
:
self.fields['parent']
它们都不是有用的,(Pdb) pprint(dir(self.fields['parent']))
[...
'bound_data',
'cache_choices',
'choice_cache',
'choices',
'clean',
'creation_counter',
'default_error_messages',
'default_validators',
'empty_label',
'empty_values',
'error_messages',
'help_text',
'hidden_widget',
'initial',
'label',
'label_from_instance',
'localize',
'prepare_value',
'queryset',
'required',
'run_validators',
'show_hidden_initial',
'to_field_name',
'to_python',
'valid_value',
'validate',
'validators',
'widget',
'widget_attrs']
看起来像我想要的,但即使那样也没有用。
我该如何处理?我需要的是根据bound_data
将queryset
child
设置为适当的子集。
答案 0 :(得分:1)
从here开始,我最终使用self._raw_value('parent')
解决了我的问题。
更新: Django 1.9删除了_raw_value()
,这是替代方案:
self.fields['parent'].widget.value_from_datadict(
self.data, self.files, self.add_prefix('parent')
)
答案 1 :(得分:0)
我认为您可以覆盖' is_valid'模型的功能。
def is_valid(self):
# run the parent validation first
valid = super(SomeForm, self).is_valid()
if not valid:
return valid
您可以查看此博客了解详情:http://chriskief.com/2012/12/16/override-django-form-is_valid/