如何根据父字段的值来限制子字段的选择? [英] How to limit the choices of a child field based on a parent field's value?

查看:134
本文介绍了如何根据父字段的值来限制子字段的选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个相当复杂的表单,依赖于模型层次结构来分配 ForeignKey 值。我需要根据其父字段的值来限制子字段的可用选项。问题是,父字段的值可能来自绑定数据(POST请求)的初始数据(GET请求)。因此,我最终复制了这个模式:

  class MyForm(forms.Form):
parent = forms .ModelChoiceField(queryset = Parent.objects.all())
child = forms.ModelChoiceField(queryset = Child.objects.all())

def __init __(self,* args,* * kwargs)
super(MyForm,self).__ init __(* args,** kwargs)

#根据'parent'的当前值限制'child'选项
如果self.is_bound和self.data.get('parent'):
self.fields ['child']。queryset = Child.objects.filter(parent__pk = self.data ['parent'])
elif self.initial.get('parent')
self.fields ['child']。queryset = Child.objects.filter(parent = self.initial ['parent'])
else:
self.fields ['child']。choices = []

感觉有一个更有效的方式来实现这一点。我缺少什么?

解决方案

你好运。 Django智能选择使这真的很简单!您必须使用ModelForm(如下)或使用 ChainedForeignKey 字段类型设置您的模型(如文档中所示)。



请注意 - 这不是确切的代码。所提供的参数与您的模型定义和结构有关。但是,第一个选项将如下所示:

  from smart_selects.form_fields import ChainedModelChoiceField 

class MyForm(forms.ModelForm):
parent = forms.ModelChoiceField(queryset = Parent.objects.all())
child = ChainedModelChoiceField('your_app','ModelName','parent','parent' )
class Meta:
model = YourModel

你必须在你的渲染页面,以便使用智能选择。当表单域被渲染时,当选择 parent 时,智能选择将包括适用的JQuery代码来制作Ajax请求,限制 children 与选定的相关的选项。


I have several rather complex forms which rely on model hierarchies to assign ForeignKey values. I need to limit the choices available to a child field based upon the value of its parent field. The problem is that the value of a parent field can come from initial data (a GET request) or from bound data (a POST request). Thus, I end up replicating this pattern a lot:

class MyForm(forms.Form):
    parent = forms.ModelChoiceField(queryset=Parent.objects.all())
    child = forms.ModelChoiceField(queryset=Child.objects.all())

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        # Limit 'child' choices based on current value of 'parent'
        if self.is_bound and self.data.get('parent'):
            self.fields['child'].queryset = Child.objects.filter(parent__pk=self.data['parent'])
        elif self.initial.get('parent'):
            self.fields['child'].queryset = Child.objects.filter(parent=self.initial['parent'])
        else:
            self.fields['child'].choices = []

I get the feeling there's a more efficient way to accomplish this. What am I missing?

解决方案

You're in luck. Django Smart Selects make this really simple! You must use a ModelForm (as below) or set up your models with a ChainedForeignKey field type (as seen in the docs).

Please note - this is NOT exact code. The arguments provided relate to your model definitions and structure. However, the first option would look something like this:

from smart_selects.form_fields import ChainedModelChoiceField

class MyForm(forms.ModelForm):
    parent = forms.ModelChoiceField(queryset=Parent.objects.all())
    child = ChainedModelChoiceField('your_app','ModelName','parent','parent')
    class Meta:
        model = YourModel

You must include JQuery in your rendered page in order to use smart selects. When the form fields are rendered, smart selects will include the applicable JQuery code to make Ajax requests when parent is selected, limiting children to choices related to the selected parent.

这篇关于如何根据父字段的值来限制子字段的选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆