Django表单在select字段中排除选项

时间:2015-01-12 21:20:49

标签: python django

我有一个模型有一个ManyToMany字段(让我们称之为"选项")与另一个模型

当我创建ModelForm时,它会显示所有选项。

有没有办法排除某些选项值或只展示其中的一些?

以下是一个例子:

models.py

class Options (model.Models):
    name = ...
    ...

class Anything (model.Models):
    ...
    options = ManyToManyField(Options)

"选项"的值在我的DB中:

["OK", 
"OK_2", 
"NOT_OK", 
"OK_3, 
"NOT_OK_2"]

让我们说我只需要显示" OK"值并隐藏或不显示" NOT_OK"值。

有没有办法用ModelForms做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以将limit_choices_to参数传递到ManyToMany字段:

from django.db.models import Q

class Anything (models.Model):
    options = models.ManyToManyField(Options,
                                     limit_choices_to=Q(name__startswith='OK'))

在django 1.7中,如果应该动态更改选项列表,您甚至可以pass a callable

答案 1 :(得分:1)

您当然可以使用Form或更常见的ModelForm过滤相关模型上的外键字段或m2m的查询集。

在表单级别执行此操作的原因很有用,因为过滤很可能基于业务逻辑,这在所有情况下都不适用,因此比根据模型定义它更具灵活性。

虽然您可以在定义表单字段时执行此操作,但最好在构建表单后执行此操作,因此它在运行时进行而不是编译时间(我刚刚经历了一些有趣的场合,这导致了我一些问题,但这是Django的早期版本!)

以下ModelForm可以完成这项工作:

class AnythingForm(ModelForm):
    options = forms.MultipleChoiceField()

    def __init__(self, **kwargs):
        super(AnythingForm, self).__init__(self, **kwargs)
        self.fields['options'].queryset = Option.objects.filter({pass in your filters here...})

    class Meta:
        model = Anything