我们如何通过 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)
要求是在不同登录的下拉列表中显示 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):
它不按登录过滤并显示所有对象。
我不想使用默认的
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)