在Django admin中编辑Group-object时,将用户对象分配给组

时间:2011-05-23 12:30:27

标签: django django-admin membership usergroups

在用户对象(编辑用户)的默认Django管理视图中,可以编辑用户的组成员资格。如果我还想反过来怎么办?即在组编辑页面中,可以选择属于正在编辑的组的用户。

正如我所看到的,Django没有从Group到User对象的ManyToMany映射,因此无法(?)为此特定情况实现ModelAdmin类。如果我可以创建一个额外的UsersOfGroup模型类并在Django的Group模型的ManyToMany字段中将其用作直通属性,那么可能有一种方法。

任何想法,这可以使用ModelAdmin技巧实现,还是只需要为编辑组创建自定义视图?

我已经检查过这两个问题了,但他们并没有做同样的事情:

Assigning a group while adding user in admin

Show group membership in admin

更新 克里斯的答案几乎就在那里。 :)该组具有对用户集的引用,但它被称为 user_set ,而不是用户。所以这些是我所做的改变:

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']

4 个答案:

答案 0 :(得分:3)

<强> 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)

答案 1 :(得分:3)

如果添加新组并同时将用户添加到组,则上述保存方法将不起作用。问题是新组不会被保存(管理员使用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

答案 2 :(得分:0)

这是一个使用Django的InlineModelAdmin对象(answered here on 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)

答案 3 :(得分:0)

我使用的是Django 2.1,并且正在使用Chris发布的解决方案,但是正如Cedric所解释的那样,当添加新组并且同时将用户添加到新组中时,它将无法正常工作。不幸的是,他的代码也无济于事,但是我可以使用此修改后的版本来使其工作:

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()


class GroupAdmin(admin.ModelAdmin):
    form = GroupAdminForm

    def save_model(self, request, obj, form, change):
        super(GroupAdmin, self).save_model(request, obj, form, change)
        if 'users' in form.cleaned_data:
            form.instance.user_set.set(form.cleaned_data['users'])


admin.site.unregister(Group)
admin.site.register(Group, GroupAdmin)