首页 > 解决方案 > Django 2.x Admin 中 InLine ManyToMany 字段的 filter_horizo​​n 或 filter_vertical

问题描述

这是我的模型关系(从 Django 2.1 官方文档复制 - 我的模型是这个的精确副本,但只有模型名称不同。):

class Person(models.Model):
    name = models.CharField(max_length=50)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(
        Person,
        through='Membership',
        through_fields=('group', 'person'),
    )

class Membership(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)

这是我的 admin.py:

class MembershipInLine(admin.StackedInline):
    model = Membership

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInLine,
    ]

我在我的个人页面上得到这样的字段: 当前视图

但相反,我希望有这种风格的观点: 期望的观点

我在官方文档filter_horizontal中找到了,但我不知道如何将它们与内联一起使用。我怎样才能做到这一点?filter_vertical

编辑:

我已经按照文档中的描述进行了尝试:

class MembershipInLine(admin.StackedInline):
    model = Membership # (and also tried with = Group.members.through)
    filter_horizontal = ('group', )

但它抛出:

(admin.E020) 'filter_horizo​​ntal[0]' 的值必须是多对多字段。

标签: pythondjangodjango-2.1

解决方案


我会咨询 auth 管理面板以获取组的权限。尝试类似的东西

class PersonAdmin(admin.ModelAdmin):
    search_fields = ()
    ordering = ()
    filter_horizontal = ('membership',)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        if db_field.name == 'membership':
            qs = kwargs.get('queryset', db_field.remote_field.model.objects)
            # Avoid a major performance hit resolving membership names which
            # triggers a content_type load:
            kwargs['queryset'] = qs.select_related('content_type')
        return super().formfield_for_manytomany(db_field, request=request, **kwargs)

https://github.com/django/django/blob/master/django/contrib/auth/admin.py#L29


推荐阅读