Les Crash-Devs d'un Passionné

Surcharger le modèle User de Django

/Catégorie/django

Temps de lecture : 3 minutes

Lorsque vous avez une gestion des utilisateurs qui est proche de celle de Django, il est possible d'étendre cette dernière en lui ajoutant des propriétés personnalisées.

Ce tutoriel considère que vous démarrez une nouvelle application.

Nouvelle application

Dans un 1er temps il faut installer l'application et lancez

python manage.py migrate

ATTENTION : ne pas lancer un

python manage.py makemigration

car on veut modifier le modèle User avant

Mise à jour du profil

Maintenant il faut créer le nouveau profil qui héritera du modèle User de django au travers AbstractUser

clipboard
Copier le code
1
2
3
4
5
from myApp.managers import UserProfilManager

class UserProfil(AbstractUser):

	follower = models.IntegerField(null=True, default=0)

Ensuite il faut ajouter dans le settings.py, la valeur correspondante au nom de votre application et le nom du modèle

AUTH_USER_MODEL = 'myApp.UserProfil'

Migration

Il est temps maintenant de préparer les changements à appliquer

python manage.py makemigrations

et de faire la migration

python manage.py migrate

IMPORTANT : Si le migrate ne fonctionne pas il faut supprimer toutes les tables sauf django_migrations et vider le contenu de cette table. Puis refaire un migrate.

Configuration de l'administration de django

Maintenant que le modèle est appliqué en base de données nous allons l'utiliser dans la partie admin

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from django.contrib import admin
from django.forms import ModelForm, CharField, PasswordInput

from myApp.models.user_profil import UserProfil
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

class UserProfilForm(ModelForm):

    password1 = CharField(label='Password', widget=PasswordInput)
    password2 = CharField(label='Password confirmation', widget=PasswordInput)

    class Meta:
        model = UserProfil
        fields = ('email', 'follower')

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserProfilForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password2"])
        if commit:
            user.save()
        return user

    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 ValidationError("Passwords don't match")
        return password2

class UserProfilChangeForm(ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = UserProfil
        fields = ('email', 'password', 'follower')

    def clean_password(self):
        return self.initial["password"]

@admin.register(UserProfil)
class ProfilAdmin(BaseUserAdmin):
    add_form = UserProfilForm
    list_display = ['first_name', 'last_name', 'follower']

    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        ('Personal info', {'fields': ('last_name', 'first_name', 'email')}),
        ('Challenges', {'fields': ('follower',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'follower', 'password1', 'password2'),
        }),
    )

Il est IMPORTANT de mettre from myApp.models.user_profil import UserProfil avant les imports django.contrib.auth sinon vous aurez une erreur de ce type

django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'myApp.UserProfil' that has not been installed

Résultat affiché dans la page d'administration

UserProfilForm est la page à afficher pour la création d'un utilisateur

creation_utilisateur_django

Tandis que UserProfilChangeForm sera utilisé pour la mise à jour d'un utilisateur.

modification_utilisateur_django

Retrouvez cet exemple sur lequel je me suis appuyé dans la documentation de Django