【问题标题】:Django - ModelChoiceField queryset based on a parent ModelChoiceFieldDjango - 基于父 ModelChoiceField 的 ModelChoiceField 查询集
【发布时间】:2014-11-15 10:49:51
【问题描述】:

我有一个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 有数千个项目。

我知道我可以在 __init__() 中覆盖 queryset,这就是我想要做的,但是,与我在 stackoverflow 中搜索的大多数情况不同,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 看起来像我想要的,但即使这样也没有用。

我该如何处理?我需要的是根据parentchildqueryset 设置为适当的子集。

【问题讨论】:

  • 看起来您正在尝试动态更改值。您不能这样做,因为__init__ 是一个初始化器,并且不会在每次值更改时调用。这篇文章可能会对您有所帮助:stackoverflow.com/questions/3233850/…
  • @karthikr self._raw_value('parent') 为我做了,谢谢!

标签: django django-forms


【解决方案1】:

我认为你可以覆盖 modelform 的 '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/

【讨论】:

  • 我可能会在clean 中执行此操作。无论如何,要验证child,我需要parent 的值,这让我回到了最初的问题——无法检索parent 的值。
【解决方案2】:

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')
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 2015-09-09
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    相关资源
    最近更新 更多