0

Gérer des comptes utilisateurs et profils personnalisés pour votre site Django

Introduction

Lorsque vous développez avec Django une application web qui nécessite une gestion de comptes, il est souvent nécessaire de personnaliser le modèle “utilisateur” par défaut fourni par Django. Dans cet article, nous allons discuter les éléments important permettant de créer un modèle d’utilisateur personnalisé et un modèle de profil associé.

Pourquoi un modèle d’utilisateur personnalisé ?

Django fournit un modèle d’utilisateur très complet, mais il peut ne pas répondre à tous vos besoins. Par exemple, vous pourriez vouloir ajouter des champs supplémentaires comme une photo de profil ou des liens vers des réseaux sociaux. Dans ces cas, il est recommandé de créer un modèle d’utilisateur personnalisé.

Créer le modèle personnalisé pour les utilisateurs

En supposant que vous ayez déjà le code de base classique d’un projet Django, par exemple généré avec la commande “django-admin startproject”, nous pouvons ajouter une app (concept spécifique à Django) que nous nommons users au sein du projet avec la commande :

python manage.py startapp

Ensuite, il faut s’assurer que l’app “users” est référencée dans le fichier settings.py du projet, dans la liste des apps (INSTALLED_APPS).

Par exemple, on aura dans le fichier settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
]

Pour créer un modèle d’utilisateur personnalisé, vous devez créer une classe qui hérite de la classe abstraite AbstractBaseUser et de la classe “mixin” PermissionsMixin (qui viennent du module django.contrib.auth).

De plus, pour accompagner votre classe User personnalisée, vous allez définir une classe UserManager qui est responsable de la création des utilisateurs et des “super utilisateurs”. Elle va hériter de la classe de base BaseUserManager et implémenter les méthodes create_user et create_superuser.

Sans entrer dans tous les détails, voici un exemple de code pour cette partie, qui va typiquement se trouver dans users/models.py au sein du package de l’application Django:

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models

# UserManager custom
class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        ...
        # code pour créer un user

    def create_superuser(self, email, password=None, **extra_fields):
        ...
        # code pour créer un superuser


# User custom
class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

Ici, il y a une chose importante à faire, du point de vue du framework, pour que les choses fonctionnent : Ajouter au fichier settings.py le paramètre AUTH_USER_MODEL avec comme valeur la chaîne correspondant au modèle des comptes utilisateurs.

AUTH_USER_MODEL = 'users.User'

En cas de doute sur la valeur affectée à ce paramètre, sachez qu’il s’agit du label de l’application (que vous retrouvez dans le fichier users/apps.py) suivi de “.” suivi du nom du modèle, c’est-à-dire dans ce cas la chaîne “users.User”.

Créer le modèle de profil

Pour ajouter des informations supplémentaires au compte utilisateur dans la base de données, vous pouvez créer un modèle de profil. En fait, c’est même recommandé. Ce modèle sera lié au modèle d’utilisateur via une relation “1 à 1” ; pour ça vous allez utiliser un champ de type OneToOneField.

Voici un exemple de définition d’un modèle nommé Profile pour le profil d’utilisateur :

class Profile(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    picture = models.ImageField(upload_to='profile_pics/')
    bio = models.TextField()

    def __str__(self):
        return f"{self.user} profile"

Nous avons ajouté la définition de la méthode spéciale __str__ que Python propose, et qui est appelée en arrière-plan chaque fois que nous utilisons la fonction str(), afin de rendre l’affichage des objets plus parlant, et cela va être utile plus loin.

Migration de la base de données

Il ne faut pas oublier l’étape incontournable de génération du code de migration de la base de données, via la commande :

python manage.py makemigrations users

Ce qui produit comme effet, par exemple :

Migrations for 'users':
  users/migrations/0001_initial.py
    - Create model User
    - Create model Profile

Bien sûr, maintenant que nous avons le code de migration, nous allons l’appliquer pour migrer l’état de notre base de données, via la commande :

python manage.py migrate

Tester le résultat

Pour tester le résultat de l’ajout de ces deux modèles, nous pourrions compléter le code de la partie UI de l’application, en écrivant entre autres une “view”, un “form” et des templates, comme le prévoit le framework Django.

Mais pour tester les choses tout de suite, nous allons utiliser le shell de Django, via la commande suivante :

python manage.py shell

Nous pouvons tester les choses dans le shell de la manière suivante :


>>> from django.contrib.auth import get_user_model
>>> User = get_user_model()
>>> u = User(email="john.doe@example.com")
>>> u.save()
>>> from users.models import Profile
>>> u_profile = Profile(user=u)
>>> u_profile.save()

>>> print(f"{u} - {u_profile}")
john.doe@example.com - john.doe@example.com profile

Vous remarquerez que nous n’avons pas importé le modèle User avec :

from exampleapp.users.models import User

Nous aurions pu. Mais nous avons plutôt utilisé la fonction get_user_model(), fournie par le module django.contrib.auth, qui permet de retourner la classe là où nous en avons besoin. Et ensuite, nous nous servons de la classe.

C’est en fait la méthode recommandée. Cela garantit que vous utilisez le bon modèle d’utilisateur, même si un modèle personnalisé a été défini. En arrière-plan, cette fonction s’appuie sur la valeur référencée dans le fichier settings.py comme vu plus haut.

Ainsi, typiquement, si vous écrivez du code de view, pour l’UI de l’application, vous écrirez ce genre de choses:

from django.contrib.auth import get_user_model

User = get_user_model()

def my_view(request):
    users = User.objects.all()
    ...

Conclusion

Dans Django, la mise en place d’un modèle personnalisé d’utilisateur et d’un modèle de profil associé est une pratique courante pour plus de flexibilité. Cela vous permet d’ajouter des champs et des fonctionnalités supplémentaires pour répondre aux besoins spécifiques de votre application.

N’hésitez pas à personnaliser ces modèles selon les besoins de votre projet.

Vous trouverez le code qui accompagne cet article dans notre Github ici : https://github.com/ContentGardeningStudio/djangoexampleapp

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Scroll to top