我们如何通过 ModelForm 查询集覆盖 Dango ModelAdmin 查询集?

How can we override Dango ModelAdmin queryset over ModelForm queryset?

要求是在不同登录的下拉列表中显示 M2M 实例。每次登录都只能看到属于自己域的实例。由于此下拉列表是 table 行值的动态列表,因此我想使用

widget  = forms.CheckboxSelectMultiple   which is part of the ModelForm where we need to pass the queryset. This queryset overrides the M2M form field definition:

 def formfield_for_manytomany(self, db_field, request, **kwargs): 

它不按登录过滤并显示所有对象。 我不想使用默认的 从下拉列表中进行选择。不太适合任何 JS 相关代码。请问清楚。分享尝试过的代码片段:

models.py:

class GroupA(models.Model):
    address = models.EmailField(
        unique=True,verbose_name='Email id of the group')
    mailboxes = models.ManyToManyField(Mailbox,
                                       related_name='my_mailboxes')

class GroupForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['mailboxes'].widget.attrs={"style":"height:100px;"}
        
    class Meta:
        model = GroupA
        fields = "__all__"
    mailboxes = forms.ModelMultipleChoiceField(
         queryset = Mailbox.objects.all(),
         widget  = forms.CheckboxSelectMultiple
     )

在admin.py

class GroupAdmin(admin.ModelAdmin):
    form = GroupForm
 
    def get_form(self, request, obj=None, **kwargs):
        kwargs['form'] = GroupForm
        Form = super().get_form(request, obj=None, **kwargs)
        return functools.partial(Form, 
mailboxes=Mailbox.objects.filter(
            domain__customer__email=request.user.email))
    '''
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "mailboxes":
            #if request.user.groups.filter(name__in=['customers']).exists():
            kwargs["queryset"] = Mailbox.objects.filter(
                domain__customer__email=request.user.email)
            #print(kwargs["queryset"], 'qqqqqq')
            for k in kwargs["queryset"]:
                print(k, 'kkkkkkkkkk')
        return super(GroupAdmin, self).formfield_for_manytomany(
            db_field, request, **kwargs)
    '''

当我们不使用 MultiCheckbox 小部件时过滤有效。想要过滤复选框。使用 django3.2。 python3.8.请指导

查看 django 模型管理代码,不知道为什么,但似乎 ModelAdmin 不遵守自定义表单中配置的 many-to-many 字段。

但是如果你想要过滤复选框,你可以在formfield_for_manytomany中做这样的事情:

from django import forms

class GroupAdmin(admin.ModelAdmin):
    # ...
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "mailboxes":
            kwargs["queryset"] = Mailbox.objects.filter(
                domain__customer__email=request.user.email
            )
            kwargs["widget"] = forms.CheckboxSelectMultiple

        return super().formfield_for_manytomany(db_field, request, **kwargs)