Résolue

Profile OneToOneField

# Héritage # Django

Gabriel Trouvé

Mentor

Dernière question de la soirée promis ^^


J'ai remis le code ci-dessous pour que ça soit plus simple.


Si je comprends bien l'intérêt de passer par un OneToOneFields est de pouvoir gérer des profiles d'utilisateurs différents par exemple.


1 :

Imaginons que je veuille deux profiles : acheteur, vendeur.

Je dois créer deux class ProfileAcheteur, ProfileVendeur ? Ou on fait tout dans la seule class Profile ?

Est-ce que c'est possible de me montrer un exemple de code dans le cas où je veux un vendeur et un client ?


2 :

Dans le modèle Profile, quand on ajoute un champs autre que user comme vendeur_id dans mon cas ci-dessous, il n'y a pas besoin de le spécifier dans def post_save_receiver ?


3 :

Et dans la fonction post_save_receiver, on utilise bien instance, created mais pas sender. C'est normal ?


Merci d'avance, décidemment je galère beaucoup sur les chapitres liés aux utilisateurs :s


from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import AbstractUser
from profil import settings


# pour rajouter des champs on passe par l'héritage de AbstractUser normalement.
# pourquoi utiliser un modele avec OneToOne ?
class CustomUser(AbstractUser):
    pass
# Dans le cas où je veux différentes données pour différents types d'utilisateurs. Ex un client, un vendeur
class Profile(models.Model):
    # on ne met pas directement la class mais on passe par le fichier de settings
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    vendeur_id = models.CharField(max_length=5)


def post_save_receiver(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)


# relier la fonction post_save_receiver à l'émetteur AUTHUSERMODEL
post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL)

Salut Gab !


Ne t'en fais pas, il y a beaucoup beaucoup de concepts dans tout ça, donc c'est normal si tu es un peu perdu au début, ça prend des mois (voire plus) à tout assimiler et on continue toujours de découvrir des choses et façons de faire.


Pour le OneToOne en fait ça permet de t'assurer que tu auras bien un seul profile associé à un utilisateur. C'est différent d'un ForeignKey qui permettrait d'associer plusieurs profils à un même utilisateur (ça peut être souhaitable dans certaines applications, tout dépend vraiment de ce que tu veux faire).


Dans cet exemple, c'est comme sur Docstring : chaque utilisateur n'a qu'un seul et unique profil. Ça permet juste de "décharger" le modèle utilisateur et de ne pas ajouter plein de champs dans le modèle utilisateur. Comme ça le modèle utilisateur gère uniquement les choses absolument essentielles (mots de passe, email, etc) et le profil gère les infos de l'utilisateur. Mais là encore, il n'y a pas de règle absolu, tu pourrais mettre tous les champs style biographique, occupation, etc, dans le modèle User.


Si on passait par un ForeignKey à la place, ça pourrait être utile si tu voulais permettre aux utilisateurs de créer plusieurs profils. Imagine une application de réseau social, tu pourrais avoir un seul et même compte utilisateur (avec un seul email et mot de passe) mais différents profils : un profil pro, un profil perso, etc.


Pour ta 2e question, tu peux là encore faire ce que tu veux selon ton application. Tu pourrais par exemple décider de créer automatiquement un id aléatoire lors de la sauvegarde du modèle. Le "created" est un booléen qui est vrai uniquement quand le profil est créé pour la première fois. Donc c'est idéal si tu souhaites comme dans cet exemple créer un ID unique la première fois et ne pas le recréer à chaque fois que le profile est sauvegardé. J'ai fait ça sur Docstring pour générer un ID unique qui servait à l'époque pour les "referrals".


from uuid import uuid4

def post_save_receiver(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance, vendor_id=str(uuid4()))


Et pour ta 3e question, on n'utilise pas sender effectivement parce qu'on n'en a pas besoin tout simplement. Il s'agit de la classe qui émet le signal, dans ce cas-ci la classe de l'utilisateur. Ça pourrait être pratique si tu souhaitais faire certaines opérations (là encore, imagine que tu as quelqu'un qui s'inscrit via un lien de "referral", tu pourrais lors de la création de l'utilisateur, aller chercher dans ta base de données l'utilisateur correspondant au "referral" pour lui donner une récompense.


J'espère que c'est un peu plus clair :)

Gabriel Trouvé

Mentor

Merci Thibault. Si tu penses qu'on peut en reparler demain de vive voix en mentorat ça peut être cool 😁

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.