问题描述
||
在用户对象(编辑用户)的默认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(),**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,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)