Django models 如何限制Django中多对多字段表单中可能的选择?

Django models 如何限制Django中多对多字段表单中可能的选择?,django-models,django-forms,many-to-many,directed-acyclic-graphs,Django Models,Django Forms,Many To Many,Directed Acyclic Graphs,这是我在一个应用程序中的模型,它描述了一个图形(准确地说是a): 每个节点可以有许多其他节点作为父节点。这里的要点是,给定节点具有一组特定的允许父节点。这就是“允许的父母列表”方法的作用。但是我如何才能得到一个只在下拉列表中显示这些节点的表单呢 目前的形式如下: class NodeForm(forms.ModelForm): class Meta: model = Node fields = ['name', 'parents'] 我在管理员处注册:

这是我在一个应用程序中的模型,它描述了一个图形(准确地说是a):

每个节点可以有许多其他节点作为父节点。这里的要点是,给定节点具有一组特定的允许父节点。这就是“允许的父母列表”方法的作用。但是我如何才能得到一个只在下拉列表中显示这些节点的表单呢

目前的形式如下:

class NodeForm(forms.ModelForm):
    class Meta:
        model = Node
        fields = ['name', 'parents']
我在管理员处注册:

class NodeAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'list_parents', 'list_children']
    form = NodeForm

admin.site.register(Node, NodeAdmin)
我想我将不得不使用类似于:

parents = forms.ModelMultipleChoiceField(queryset=node.list_of_allowed_parents())
但是如何将特定的
节点
传递到forms.py中的定义


理想情况下,该约束将添加到模型中
ManyToManyField
提供了参数
选项
限制选项
,但似乎无法在此处添加
自我。列出允许的父项

您可以调用表单
\uuu初始
方法来更新父项查询集。可以通过更新表单kwargs从视图中发送节点,或者如果更新同一对象,可以使用实例

forms.py

class NodeForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        node = kwargs.pop('node', None)
        # node = kwargs.pop('instance', None)

        super(NodeForm, self).__init__(*args, **kwargs) 
        self.fields['parents'].queryset = node.list_of_allowed_parents()

    class Meta: 
        model = Node 
        fields = ['name', 'parents']
你可以试试这个

视图.py

如果您使用的是基于类的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
如果您使用的是基于功能的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)

您可以调用表单
\uuuuu init\uuuu
方法来更新父查询集。可以通过更新表单kwargs从视图中发送节点,或者如果更新同一对象,可以使用实例

forms.py

class NodeForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        node = kwargs.pop('node', None)
        # node = kwargs.pop('instance', None)

        super(NodeForm, self).__init__(*args, **kwargs) 
        self.fields['parents'].queryset = node.list_of_allowed_parents()

    class Meta: 
        model = Node 
        fields = ['name', 'parents']
你可以试试这个

视图.py

如果您使用的是基于类的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
如果您使用的是基于功能的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)

您正在寻找可调用的many2manyField参数


此处讨论:

您正在寻找可调用的many2manyField参数

此处讨论:

您可以试试这个

视图.py

如果您使用的是基于类的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
如果您使用的是基于功能的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
你可以试试这个

视图.py

如果您使用的是基于类的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
如果您使用的是基于功能的视图

 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)
 def get_form_kwargs(self): 
    """Returns the keyword arguments for instantiating the form.""" 
    kwargs = super(YourViewName, self).get_form_kwargs() 
    node = get_object_or_404(Node, pk=self.kwargs['node_id'])
    kwargs['node'] = node
    return kwargs
node = get_object_or_404(Node, pk=node_id)
form = NodeForm(node=node)

这是“旧式”。现在可以使用
将选项限制为
:)
/
应该做什么?当我在
\uuuu init\uuuu
中留下第二行时,我得到了一个错误
'list'对象没有属性'iterator'
,当我删除它时,第一个错误是
'NoneType'对象没有属性'list\'u of \u allowed\u parents'
。实际上不清楚如何在表单中传递节点对象。。所以它显示了这两种方式,无论是从节点键还是从实例键,以便您可以根据需要使用。我将使用任何有效的方法。目前,我不知道如何将节点键或实例获取到forms.py。因此,您可以告诉我您在哪里使用该表单查看.py。这样我就可以解决您的问题。这是“旧样式”。现在可以使用
将选项限制为
:)
/
应该做什么?当我在
\uuuu init\uuuu
中留下第二行时,我得到了一个错误
'list'对象没有属性'iterator'
,当我删除它时,第一个错误是
'NoneType'对象没有属性'list\'u of \u allowed\u parents'
。实际上不清楚如何在表单中传递节点对象。。所以它显示了这两种方式,无论是从节点键还是从实例键,以便您可以根据需要使用。我将使用任何有效的方法。目前,我不知道如何获取forms.py的节点键或实例。因此,请您告诉我您在哪里使用该表单。这样我就可以解决您的问题。我的问题与上面提到的相同:“我看不到访问‘self’的方法。我的问题与上面提到的相同:“我看不到访问‘self’的方法。”