Django ModelMultipleChoiceField 相关 m2m 对象的延迟加载

Elg*_*rov 5 python django many-to-many django-admin

我尝试在模型的管理页面之一中使用django.forms.ModelMultipleChoiceField,以便m2m通过表单更新关系。我还指定django.contrib.admin.widgets.FilteredSelectMultiple为表单字段的小部件并成功实现了我的目的。问题是,由于我有超过 10K 的相关对象,所有这些对象都作为选项包含在表单页面中,这使得页面非常慢。django.contrib.auth.models.Group为了说明这个问题,我在这里添加了模型和相关“用户”上的本案例设备的类比。

管理员.py

from django.contrib import admin
from django.contrib.auth.models import Group

from forms import GroupAdminForm

admin.site.unregister(Group)  # get rid of default one


class GroupAdmin(admin.ModelAdmin):
    form = GroupAdminForm
    filter_horizontal = ['permissions']

admin.site.register(Group, GroupAdmin)
Run Code Online (Sandbox Code Playgroud)

表格.py

from django import forms
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.models import Group


User = get_user_model()


class GroupAdminForm(forms.ModelForm):
    class Meta:
        model = Group
        exclude = []

    users = forms.ModelMultipleChoiceField(
         queryset=User.objects.all(),
         required=False,
         widget=FilteredSelectMultiple('users', False)
    )

    def __init__(self, *args, **kwargs):
        super(GroupAdminForm, self).__init__(*args, **kwargs)
        if self.instance.pk:
            self.fields['users'].initial = self.instance.user_set.all()

    def save_m2m(self):
        self.instance.user_set.set(self.cleaned_data['users'])

    def save(self, *args, **kwargs):
        instance = super(GroupAdminForm, self).save()
        self.save_m2m()
        return instance
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,默认的管理更改页面Group被禁用并再次实现,其中还包括组用户的输入。这是我添加 1000 个测试用户对象后的样子:在此输入图像描述

如您所见,所有 1000 个用户都作为选项包含在内。我的问题是,如何才能实现禁用最初显示它们并在用户在过滤框中键入内容时显示它们?

注意:请不要建议我使用admin.ModelAdmin.raw_id_fields,因为这不方便用户使用。另外,最好在没有任何第三方包的帮助下解决这个问题。