在Django Admin中创建用户时将用户添加到权限组

时间:2018-07-05 21:14:58

标签: python django django-admin django-users

创建用户时,我会自动将用户添加到权限组。我听说过user.groups.add(group)和group.user_set.add(user)。但这是行不通的。我的最终目的是拥有3种用户:

  1. SuperAdmin:一个超级管理员来管理站点。
  2. 管理员:用户管理员。可以管理普通用户。上传照片,添加新用户以进行管理,等等。
  3. 普通用户:将使用aplicación的普通用户。他们没有任何权限,只需登录站点即可,但没有adminSite。

MODELS.PY

keys:(7) ["name", "detail", "category"]

ADMIN.PY

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

2 个答案:

答案 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)