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
- Я хочу добавить это на сайт администратора Django, чтобы администратор мог создавать группы пользователей, а также назначать пользователей в группы пользователей .
- Пользователю должно быть разрешено быть только в одной группе пользователей
- Пользователю также не обязательно быть в группе
- Не нужно поле usergroup в моей модели пользователя
Ниже приведено то, что я имею для своего административного сайта на данный момент.
class UserGroupAdmin(admin.ModelAdmin):
list_display = ('name',)
search_fields = ('name',)
filter_horizontal = ('users',)
admin.site.register(UserGroup, UserGroupAdmin)
При создании группы, добавлении пользователей и т.д. это выглядит следующим образом
Я думал изменить набор запросов, чтобы они показывали только пользователей, которые не находятся в группе, и пользователей, которые в настоящее время находятся в группе
Что означает.
- Под доступными пользователями Вам будет разрешено добавлять / просматривать только тех пользователей, которые еще не состоят в группе.
- Под выбранным пользователем Просмотр пользователей, уже находящихся в данной группе.
Вопрос
Я не уверен, как подходить к изменению набора запросов.
Нижеприведенный вариант отлично работает для отображения только пользователей, не входящих в группу.
Но теперь я не могу увидеть пользователей, которые уже находятся в группе "Текущие".
Это означает, что я не могу удалить пользователей из группы, а только добавить их.
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)