如何在Django的ModelForm中过滤值?

27 投票
5 回答
34008 浏览
提问于 2025-04-15 23:46

我正在尝试使用ModelForm来添加我的数据。这个功能运行得很好,但有一个问题,就是外键下拉列表显示了所有的值,而我只想让它显示与当前登录用户相关的值。

这是我想添加的ExcludedDate模型:

class ExcludedDate(models.Model):
    date = models.DateTimeField()
    reason = models.CharField(max_length=50)
    user = models.ForeignKey(User)
    category = models.ForeignKey(Category)
    recurring = models.ForeignKey(RecurringExclusion)

    def __unicode__(self):
        return self.reason

这是类别的模型,也就是我想根据用户限制的关系表:

class Category(models.Model):
    name = models.CharField(max_length=50)
    user = models.ForeignKey(User, unique=False)

    def __unicode__(self):
        return self.name

最后,这是表单的代码:

class ExcludedDateForm(ModelForm):

    class Meta:
        model = models.ExcludedDate
        exclude = ('user', 'recurring',)

我该怎么做才能让表单只显示那些类别,其中的category.user等于当前登录的用户呢?

5 个回答

1

我知道这个问题有点老了,但它是谷歌搜索结果中的前几个,所以我想分享一下我是怎么做到的。

class CustomModelFilter(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return "%s %s" % (obj.column1, obj.column2)

class CustomForm(ModelForm):
    model_to_filter = CustomModelFilter(queryset=CustomModel.objects.filter(active=1))

    class Meta:
        model = CustomModel
        fields = ['model_to_filter', 'field1', 'field2']

这里的'model_to_filter'是"CustomModel"模型的一个外键。

我喜欢这个方法的原因是:在"CustomModelFilter"中,你还可以改变模型对象在创建的选择字段中的默认显示方式,就像我上面做的那样。

1

这里有个例子:

models.py

class someData(models.Model):
    name = models.CharField(max_length=100,verbose_name="some value")

class testKey(models.Model):
    name = models.CharField(max_length=100,verbose_name="some value")
    tst = models.ForeignKey(someData)

class testForm(forms.ModelForm):
    class Meta:
        model = testKey

views.py

...
....
....
    mform = testForm()
    mform.fields["tst"] = models.forms.ModelMultipleChoiceField(queryset=someData.objects.filter(name__icontains="1"))
...
...

或者你可以试试这样的写法:

class testForm(forms.ModelForm):
    class Meta:
        model = testKey

def __init__(self,*args,**kwargs):
    super (testForm,self ).__init__(*args,**kwargs)
    self.fields['tst'].queryset = someData.objects.filter(name__icontains="1")
34

你可以在初始化的时候自定义你的表单。

class ExcludedDateForm(ModelForm):
    class Meta:
        model = models.ExcludedDate
        exclude = ('user', 'recurring',)
    def __init__(self, user=None, **kwargs):
        super(ExcludedDateForm, self).__init__(**kwargs)
        if user:
            self.fields['category'].queryset = models.Category.objects.filter(user=user)

在视图中,当你创建表单的时候,除了标准的表单参数外,你还需要指定当前用户:

form = ExcludedDateForm(user=request.user)

撰写回答