filter_horizon или filter_vertical для поля InLine ManyToMany в Django 2.x Admin

Вот мое отношение к модели (скопировано из официальной документации 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,
    ]

Я получаю поле на своей странице Person следующим образом: Текущий вид

Но вместо этого я хотел бы иметь такой стиль просмотра: Желаемый вид

Я нашел filter_horizontal и filter_vertical в официальная документация, но я не могу понять, как я могу использовать их со встроенным. Как я могу это сделать?

Изменить:

Я пробовал, как описано в документах:

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

Но выдает:

(admin.E020) Значение 'filter_horizontal[0]' должно быть полем "многие ко многим".


person thiras    schedule 02.10.2018    source источник
comment
Согласно документам, горизонтальный фильтр и вертикальный фильтр предназначены для многих полей. Поэтому в вашем случае их можно использовать с группой.   -  person not2acoder    schedule 02.10.2018
comment
@not2acoder Моя модель уже ManyToMany   -  person thiras    schedule 02.10.2018
comment
Таким образом, filter_horizontal можно использовать в групповом администраторе, модели с полем manytomany, а не с человеком.   -  person not2acoder    schedule 02.10.2018
comment
Это не работает ни с вашим предложением, ни с моим первым подходом (с использованием промежуточной модели) @not2acoder, как вы можете видеть в разделе редактирования.   -  person thiras    schedule 02.10.2018
comment
Поскольку вы используете Intermediate through model , в этом случае будет непросто отобразить filter_horizontal, см. это: stackoverflow.com/questions/44714416/   -  person not2acoder    schedule 02.10.2018


Ответы (1)


Я бы проконсультировался с панелью администратора авторизации для разрешений группы. Попробуйте что-то вроде

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

person Harry Moreno    schedule 02.10.2018
comment
Я пробовал именно так, как вы предлагаете. Я все еще получаю ту же ошибку. - person thiras; 02.10.2018