Добавить пользователя в группу разрешений при создании пользователя в Django Admin - PullRequest
0 голосов
/ 06 июля 2018

Я бы добавил пользователя в группу разрешений автоматически при создании пользователя. Я слышал о user.groups.add (группа) и group.user_set.add (пользователь). Но это не работает. Моя последняя цель - иметь 3 вида пользователей:

  1. SuperAdmin: один суперадмин для управления сайтом.
  2. Администраторы: администраторы пользователей. Которым могут управлять обычные пользователи. Загрузка фотографий, добавление новых пользователей для управления и т. Д.
  3. Обычные пользователи: обычные пользователи, которые будут использовать aplicación. У них нет разрешения, просто войдите на сайт, но не на сайт администратора.

MODELS.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'

ADMIN.PY

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

Я думаю, что решение должно быть здесь, но оно не работает:

СОХРАНИТЬ ФУНКЦИЮ ПОЛЬЗОВАТЕЛЯ

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

Ответы [ 2 ]

0 голосов
/ 27 июля 2018

Это решение, которое я нашел.

@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)
0 голосов
/ 06 июля 2018

Это потому, что администратор django не вызывает метод save вашей формы с commit=True.

Если вы действительно хотите, чтобы это делалось только для пользователей, сохраненных от администратора, вам следует переопределить метод save_model на ModelAdmin. Это означает, что вам нужно отменить регистрацию UserModelAdmin из django.contrib.admin и создать свой собственный UserModelAdmin.

Если вы хотите, чтобы это было сделано глобально в вашем приложении, посмотрите на сигнал post_save .

...