Python Django Администратор сайта Пользовательский набор запросов

Фон

У меня есть модель Usergroup

class UserGroup(models.Model):
    name = models.CharField(max_length=255, unique=True)
    users = models.ManyToManyField(User, blank=True)

    def __str__(self):
        return self.name
  1. Я хочу добавить это на сайт администратора Django, чтобы администратор мог создавать группы пользователей, а также назначать пользователей в группы пользователей
  2. .
  3. Пользователю должно быть разрешено быть только в одной группе пользователей
  4. Пользователю также не обязательно быть в группе
  5. Не нужно поле usergroup в моей модели пользователя

Ниже приведено то, что я имею для своего административного сайта на данный момент.

class UserGroupAdmin(admin.ModelAdmin):
    list_display = ('name',)
    search_fields = ('name',)

    filter_horizontal = ('users',)

admin.site.register(UserGroup, UserGroupAdmin)

При создании группы, добавлении пользователей и т.д. это выглядит следующим образом

enter image description here

Я думал изменить набор запросов, чтобы они показывали только пользователей, которые не находятся в группе, и пользователей, которые в настоящее время находятся в группе

Что означает.

  1. Под доступными пользователями Вам будет разрешено добавлять / просматривать только тех пользователей, которые еще не состоят в группе.
  2. Под выбранным пользователем Просмотр пользователей, уже находящихся в данной группе.

Вопрос

Я не уверен, как подходить к изменению набора запросов.

Нижеприведенный вариант отлично работает для отображения только пользователей, не входящих в группу.

Но теперь я не могу увидеть пользователей, которые уже находятся в группе "Текущие".

Это означает, что я не могу удалить пользователей из группы, а только добавить их.

class UserGroupAdmin(admin.ModelAdmin):
    filter_horizontal = ('users',)

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == 'users':
            kwargs['queryset'] = User.objects.filter(usergroup__isnull=True)
        return super().formfield_for_manytomany(db_field, request, **kwargs)

admin.site.register(UserGroup, UserGroupAdmin)

Вы можете немного изменить подход с помощью:

from django.db.models import Q


class UserGroupAdmin(admin.ModelAdmin):
    filter_horizontal = ('users',)

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == 'users':
            kwargs['queryset'] = User.objects.filter(
                Q(usergroup=None)
                | Q(usergroup=self.request.resolver_match.kwargs.get('object_id'))
            )
        return super().formfield_for_manytomany(db_field, request, **kwargs)


admin.site.register(UserGroup, UserGroupAdmin)

Но я согласен, что это некрасиво, отчасти потому, что ModelAdmin не не порождает отдельный объект представления для каждого запроса, и поэтому не имеет такого большого "контекста" для каждого запроса.

Это было мое окончательное решение благодаря willeM_ Van Onsem

class UserGroupAdmin(admin.ModelAdmin):
    filter_horizontal = ('users',)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        if db_field.name == 'users':
            object_id = request.resolver_match.kwargs.get('object_id')
            kwargs['queryset'] = User.objects.filter(
                Q(usergroup=None) | Q(usergroup=object_id)
            )
        return super().formfield_for_manytomany(db_field, request, **kwargs)

admin.site.register(UserGroup, UserGroupAdmin)
Вернуться на верх