Присвоить пользовательские объекты группе при редактировании группового объекта в администраторе Django - PullRequest
6 голосов
/ 23 мая 2011

В стандартном представлении администратора Django для пользовательского объекта (редактирование пользователя) можно редактировать членство в группах пользователей.Что если бы я хотел этого и наоборот?Т.е. на странице редактирования группы можно выбрать пользователей, которые принадлежат редактируемой группе.

Как я вижу, у Django нет отображения ManyToMany из объекта Group в User, что делает невозможным (?)реализовать класс ModelAdmin для этого конкретного случая.Если бы я мог создать дополнительный класс модели UsersOfGroup и использовать его в поле ManyToMany модели Django в качестве сквозного атрибута, то мог бы быть способ.

Любые идеи, можно ли это реализовать с помощью трюков ModelAdmin или сделатьМне просто нужно создать собственное представление для редактирования групп?

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

Назначение группы во времядобавление пользователя в admin

и

Показать членство в группе в admin

Обновлено: Ответ от Криса былпочти готово.:) Группа имеет ссылку на набор пользователей, но она называется user_set , а не users .Итак, это изменения, которые я сделал:

if self.instance and self.instance.pk:
    self.fields['users'].initial = self.instance.user_set.all()

и

if group.pk:
    group.user_set = self.cleaned_data['users']

Ответы [ 3 ]

3 голосов
/ 02 июня 2011

Метод сохранения выше не будет работать, если вы добавите новую группу и одновременно добавите пользователей в группу. Проблема в том, что новая группа не будет сохранена (администратор использует commit = False) и не будет иметь первичного ключа. Поскольку цель save_m2m () состоит в том, чтобы позволить вызывающему представлению обрабатывать сохранение объектов m2m, я создал объект сохранения, который оборачивает старый метод save_m2m в новый метод.

def save(self, commit=True):
    group = super(GroupAdminForm, self).save(commit=commit)

    if commit:
        group.user_set = self.cleaned_data['users']
    else:
        old_save_m2m = self.save_m2m
        def new_save_m2m():
            old_save_m2m()
            group.user_set = self.cleaned_data['users']
        self.save_m2m = new_save_m2m
    return group
3 голосов
/ 23 мая 2011

YourApp / admin.py

from django import forms
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.contrib.admin.widgets import FilteredSelectMultiple

from django.contrib.auth.models import User, Group

class GroupAdminForm(forms.ModelForm):
    users = forms.ModelMultipleChoiceField(
        queryset=User.objects.all(), 
        required=False,
        widget=FilteredSelectMultiple(
            verbose_name=_('Users'),
            is_stacked=False
        )
    )

    class Meta:
        model = Group

    def __init__(self, *args, **kwargs):
        super(GroupAdminForm, self).__init__(*args, **kwargs)

        if self.instance and self.instance.pk:
            self.fields['users'].initial = self.instance.users.all()

    def save(self, commit=True):
        group = super(GroupAdminForm, self).save(commit=False)

        if commit:
            group.save()

        if group.pk:
            group.users = self.cleaned_data['users']
            self.save_m2m()

        return group

class GroupAdmin(admin.ModelAdmin):
    form = GroupAdminForm

admin.site.unregister(Group)
admin.site.register(Group, GroupAdmin)
0 голосов
/ 31 января 2017

Вот более простой подход, в котором используются объекты InlineModelAdmin Джанго ( здесь ответили на Qubanshi.cc )

from django.contrib.auth.admin import GroupAdmin
from django.contrib.auth.models import User, Group

class UserSetInline(admin.TabularInline):
    model = User.groups.through
    raw_id_fields = ('user',)  # optional, if you have too many users

class MyGroupAdmin(GroupAdmin):
    inlines = [UserSetInline]

# unregister and register again
admin.site.unregister(Group)
admin.site.register(Group, MyGroupAdmin)
...