首页 文章

如何使用ModelForm过滤Django表单中的值?

提问于
浏览
14

我正在尝试使用ModelForm来添加我的数据 . 它运行良好,但ForeignKey下拉列表显示所有值,我只希望它显示与登录用户相关的值 .

这是我的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等于登录用户的类别子集?

3 回答

  • 21

    您可以在 init 中自定义表单

    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)
    
  • 0

    这里的例子:

    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"))
    ...
    ...
    

    Or u can try something like this:

    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")
    
  • 0

    我知道这是旧的;但它是最早的Google搜索结果之一,所以我想我会添加我发现的方式 .

    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”模型的ForiegnKey

    为什么我喜欢这种方法:在“CustomModelFilter”中,您还可以更改Model对象在创建的ChoiceField中显示的默认方式,如上所述 .

相关问题