2 votes

Comment utiliser un ModelForm personnalisé dans l'administration utilisateur

Je cherche à limiter les possibilités des utilisateurs standards dans l'application User de l'admin de Django, afin d'éviter la possibilité d'une élévation de privilèges.

J'ai essayé l'approche mentionnée dans la documentation : https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form

class UserAdmin(BaseUserAdmin):
    form = UserForm
    inlines = (UserProfileInline,)

    def get_form(self, request, obj=None, **kwargs):
       if request.user.is_superuser:
           kwargs["form"] = SuperUserForm
       return super().get_form(request, obj, **kwargs)

class UserForm(ModelForm):
    class Meta:
        model = User
        exclude = ("is_superuser",) # c'est juste un exemple

class SuperUserForm(ModelForm):
    class Meta:
        model = User
        fields = "__all__"

Malheureusement, cela entraîne une telle erreur :

"Clé 'is_superuser' non trouvée dans 'UserForm'. Les choix sont: date_joined, email, first_name, groups, is_active, is_staff, last_login, last_name, password, user_permissions, username."

Si je décidais d'exclure "groups" :

"Clé 'groups' non trouvée dans 'UserForm'. Les choix sont: date_joined, email, first_name, is_active, is_staff, is_superuser, last_login, last_name, password, user_permissions, username."

0voto

user3193620 Points 89

Je finis par adopter une approche totalement différente :

class UserAdmin(BaseUserAdmin):

    def has_change_permission(self, request, obj=None):
        if obj != request.user and not request.user.is_superuser:
            return False
        return True

    def changelist_view(self, request, extra_context=None):
        if request.user.is_superuser:
            return super().changelist_view(request, extra_context)

        return HttpResponseRedirect(
            reverse(
                "admin:%s_%s_change" % (self.model._meta.app_label, self.model._meta.model_name),
                args=(request.user.id,),
            )
        )

    def get_fieldsets(self, request, obj=None):
        fieldsets = list(super().get_fieldsets(request, obj))
        if request.user.is_superuser:
            return fieldsets

        return [
            (None, {"fields": ("username", "password")}),
            ("Informations personnelles", {"fields": ("first_name", "last_name", "email")}),
        ]

Je ne sais pas si c'est "Djangoish" mais cela semble fonctionner comme prévu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X