创建用户时,我会自动将用户添加到权限组。我听说过user.groups.add(group)和group.user_set.add(user)。但这是行不通的。我的最终目的是拥有3种用户:
keys:(7) ["name", "detail", "category"]
from django.db import models
from django.contrib.auth.models import AbstractUser, Group
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class MyUser(AbstractUser):
descripcion = models.TextField(blank=True)
telefono = models.PositiveSmallIntegerField(default=000)
avatar = models.ImageField(upload_to='users/avatar/', blank=True)
def __str__(self):
return self.username
class RegularUser(MyUser):
MyUser.is_staff = False
MyUser.is_superuser = False
class Meta:
verbose_name = 'Usuario Regular'
verbose_name_plural = 'Usuarios Regulares'
class AdminUser(MyUser):
usuarios = models.ManyToManyField(RegularUser, help_text="Selecciona los usuarios que administra")
MyUser.is_staff = True
class Meta:
verbose_name = 'Administrador'
verbose_name_plural = 'Adminsitradores'
我认为解决方案必须在这里,但是不起作用:
from django.contrib import admin
from django import forms
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import Group
from myApp.models import MyUser, RegularUser, AdminUser
# Register your models here.
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required fields,
plus a repeated password"""
password1 = forms.CharField(label='Contraseña', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repita Contraseña',
widget=forms.PasswordInput)
class Meta:
model = MyUser
fields = ('email',
'first_name',
'last_name',
'telefono',
'avatar',
'groups',)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Las contraseñas no coinciden")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on the user
, but replaces the password field with admin's password
hash display field"""
password = ReadOnlyPasswordHashField()
class Meta:
model = MyUser
fields = ('username',
'email',
'password',
'first_name',
'last_name',
'descripcion',
'telefono',
'avatar',
)
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class AdminCreationForm(forms.ModelForm):
"""A form for creating new Admin users. Including all required fields,
plus a repeated password"""
password1 = forms.CharField(label='Contraseña', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repita Contraseña', widget=forms.PasswordInput)
# usuarios = forms.CharField(label= 'Usuarios', widget=forms.SelectMultiple(choices=RegularUser.objects.all()))
class Meta:
model = AdminUser
fields = ('username',
'email',
'password',
'telefono',
'avatar',
'usuarios',
'groups',)
def clean_password2(self):
# Check that the 2 password entries match
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise ValueError("Las contraseñas no coinciden")
return password2
# def _save_m2m(self):
# user = super().save(commit=False)
# self.instance.user_set = self.cleaned_data['user']
def save(self, commit=True):
# Save the commit password in hashed form
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
# Set the current User as admin user
user.is_staff = True
if commit:
user.save()
group = Group.objects.get(name="Administradores")
user.groups.add(group)
# group.user_set.add(user)
# group.save()
return user
@receiver(post_save, sender=AdminUser)
def post_save_admin(sender, instance, **kwargs):
if kwargs['created'] and instance.is_staff:
grupo = Group.objects.get(name="Administradores")
grupo.user_set.add(instance)
class AdminChangeForm(forms.ModelForm):
""" A form for updating Administrators. Includes all the fields on the user
, but replaces the password field with admin's password hash display field"""
password = ReadOnlyPasswordHashField()
class Meta:
model = AdminUser
fields = ('username',
'email',
'password',
'first_name',
'last_name',
'descripcion',
'telefono',
'avatar',
'usuarios',
'groups',
)
def clean_password(self):
# Regardless of what the admin provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class AdminUserAdmin(BaseUserAdmin):
# The forms to add and change admin instances
form = AdminChangeForm
add_form = AdminCreationForm
# The fields to be used in displaying the Admin model.
# These overrides the definitions on the base AdminUserAdmin
# that reference specific fields on auth.User
list_display = ('username', 'email',)
list_filter = ('last_login',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Información Personal', {'fields': ('first_name', 'last_name', 'descripcion', 'avatar', 'telefono',)}),
('Administración', {'fields': ('is_staff', 'usuarios','groups')}),
)
# add_fieldsets is not a standard Modeladmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'telefono', 'password1', 'password2', 'usuarios','groups')}
),
)
search_fields = ('username',)
ordering = ('username',)
filter_horizontal = ()
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('username', 'email', 'is_staff')
list_filter = ('is_staff',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name', 'descripcion', 'avatar', 'telefono',)}),
('Permissions', {'fields': ('is_staff', 'is_superuser')}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'telefono', 'password1', 'password2',)}
),
)
search_fields = ('username',)
ordering = ('username',)
filter_horizontal = ()
# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
admin.site.register(AdminUser, AdminUserAdmin)
# @admin.register(MyUser)
# class MyUserAdmin(admin.ModelAdmin):
# pass
# @admin.register(AdminUser)
# class AdminUserAdmin(admin.ModelAdmin):
# # The forms to add and change Admin instances:
# form = AdminChangeForm
@admin.register(RegularUser)
class RegularUserAdmin(admin.ModelAdmin):
pass
答案 0 :(得分:1)
这是因为django管理员没有使用save
来调用表单的commit=True
方法。
如果您确实只希望对从管理员保存的用户执行此操作,则应覆盖ModelAdmin
上的save_model method。这意味着您需要从UserModelAdmin
取消注册django.contrib.admin
并创建自己的UserModelAdmin
。
如果您希望在应用程序中全局完成此操作,请查看post_save signal。
答案 1 :(得分:0)
这是我找到的解决方法。
@receiver(post_save, sender= AdminUser)
def add_admin_permission(sender, instance, created, **kwargs):
if created:
grupo = Group.objects.get(id=1)
grupo.user_set.add(instance)