我使用 ModelForm 从模型创建表单,以便在我网站的各个地方使用。表单有一个外键字段,需要根据用户进行过滤。我已经成功地做到了这一点:

class TestForm(ModelForm):
    def __init__(self,user,*args,**kwargs):
        super (TestForm,self ).__init__(*args,**kwargs) # populates the post
        self.fields['controller'].queryset = Controller.objects.filter(user=user)

    class Meta:
        model = Test
        exclude = ['customer']

然后在我看来使用:form = TestForm(user)
这对于我在 Django Admin 之外的表单工作正常,但我的站点要求模型也可以在 Django Admin 中编辑。所以我将此代码用于我的 ModelAdmin,基于 Django Docs
class TestAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = SuTestForm
        else:
            kwargs['form'] = TestForm(request.user)
        return super(TestAdmin, self).get_form(request, obj, **kwargs)

我认为这应该像我的其他表单一样工作,但我从 django 得到这个错误:invalid literal for int() with base 10: 'TestForm'
经过一番谷歌搜索后,我遇到了这种将查询集过滤放在 ModelAdmin 中的方法:
form = super(TestAdmin, self).get_form(request, obj, **kwargs)
form.base_fields['controller_fk'].queryset = Controller.objects.filter(custid=cust)
return form

这工作得很好,但它确实需要我创建看起来不太干的 ModelForm 的多个副本。所以我想有谁知道如何让我的 ModelForm 查询集返回到 ModelAdmin 表单中?

最佳答案

问题在于您实际上是在 else 子句中实例化表单,而另一个子句返回的是类而不是实例。两个分支都需要返回一个类。

不幸的是,ModelAdmin 类中没有简单的钩子(Hook)来为表单实例化提供额外的 kwargs:它发生在 changeform_view 方法的深处,这比它应该更难覆盖。您需要做一些聪明的事情来返回一个包含从 get_form 中烘焙的用户值的类。

关于python - Django ModelAdmin 从 ModelForm 获取查询集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28078419/

10-11 04:04