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

|| 在用户对象(编辑用户)的默认Django admin视图中,可以编辑用户的组成员身份。如果我也想这样做又该怎么办?即在组编辑页面中,可以选择属于正在编辑的组的用户。 如我所见,Django没有从Group到User对象的ManyToMany映射,这使得在这种情况下无法实现ModelAdmin类成为可能。如果我可以制作一个额外的UsersOfGroup模型类,并将其用于Django的Group模型的ManyToMany字段中,作为直通属性,则可以找到一种方法。 有什么想法吗,是否可以使用ModelAdmin技巧来实现,还是只需要为编辑组创建一个自定义视图? 我已经检查了另外两个问题,但是它们做的不完全相同: 在管理员中添加用户时分配组 和 在管理员中显示组成员身份 更新: 克里斯的答案就在那里。 :)该组具有对用户集的引用,但是它称为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\']
    
已邀请:
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)
    
如果您添加新组并同时将用户添加到该组,则上述保存方法将不起作用。问题在于新组将无法保存(管理员使用commit = False),并且没有主键。由于save_m2m()的目的是允许调用视图处理保存的m2m对象,因此我创建了一个save对象,该对象将旧的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
    
这是使用Django的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)
    
我使用的是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)
    

要回复问题请先登录注册