在用户对象(编辑用户)的默认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']
答案 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)