• 12 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 15/07/2024

Créez des relations de type Many-to-One avec une clé étrangère

Utilisez une clé étrangère pour une relation un-à-plusieurs

Jusqu'à présent, nous avons travaillé avec un seul modèle à la fois. Nous créons des objets Band, et nous créons des objets Listing, mais nous ne travaillons qu'avec l'un d'entre eux à la fois. Il est temps de les réunir !

Pensez aux entités du monde réel que nos modèles représentent. Les différentes listes d’articles que nous avons : posters, vêtements, etc., ils sont tous liés à un groupe. Un utilisateur peut arriver sur le site et être intéressé par la liste des articles d'un groupe spécifique qui l'intéresse. Ce serait formidable si nous pouvions permettre à l'utilisateur d'afficher une page avec les annonces uniquement liées à ce groupe.

Pour ce faire, nous devons créer une relation entre le modèle Band et le modèle Listing.

L'une des relations les plus courantes entre deux modèles est la relation « one-to-many » (un-à-plusieurs).

Par exemple, nous pourrions dire qu'un Band peut avoir de nombreux Listing apparentés, mais chaque Listing ne peut avoir qu'un seul Band apparenté.

Ainsi, nous pourrions avoir un T-shirt, une affiche et un billet de concert tous liés au groupe « De La Soul ». Le groupe est lié à 3 annonces, mais chacune de ces annonces n’est liée qu’à un seul groupe. Un article ne peut pas être lié à la fois à « De La Soul » et à « Foo Fighters » en même temps.

Voyons comment créer une relation « one-to-many » entre les modèles Band et Listing.

Examinons quelques données sur nos deux tables dans la base de données (certains champs/colonnes ont été omis).

Band 

id

name

1

De La Soul

2

Foo Fighters

3

Cut Copy

Listing 

id

title

1

T-shirt Cut Copy

2

Affiche tournée De La Soul

3

Affiche du single des Foo Fighters

Si chacune de nos annonces, en un sens, « appartient » à l'un des groupes, nous pouvons ajouter une colonne à la table des annonces et y indiquer à quel groupe cette annonce appartient, ou plutôt, nous indiquons l'identifiant du groupe auquel elle appartient, comme ceci :

Listing 

id

title

band_id

1

T-shirt Cut Copy

3

2

Affiche tournée De La Soul

1

3

Affiche du single des Foo Fighters

2

Cette nouvelle colonne que nous avons ajoutée, band_id, est connue comme une clé étrangère, car elle contient l'identifiant (ou la « clé ») d'une autre table.

Cela suggère que nous devons ajouter un nouveau champ au modèle Listing, pour agir comme un lien vers le modèle Band, et il y a un type spécial de champ pour cela, appelé ForeignKey.

Ajoutons maintenant une clé étrangère au modèle Listing.

class Listing(models.Model):

   ...
   band = models.ForeignKey(Band, null=True, on_delete=models.SET_NULL)

Nous nommons le champ band. Cela signifie que nous pouvons obtenir le groupe de n'importe quelle annonce en appelant listing.band, ce qui sera très pratique plus tard.

Nous passons également trois arguments à ForeignKey :

  • le modèle auquel on veut se rattacher : Band ;

  • null=True: parce que nous voulons permettre la création d’annonces même si elles ne sont pas directement liées à un groupe ;

  • on_delete=models.SET_NULL : c'est ici que nous décidons de la stratégie à suivre lorsque les objetsBand sont supprimés. Il existe de multiples options pour cela, comme par exemple :

    • définir le champ band comme nul en utilisant models.SET_NULL,

    • définir le champ band à sa valeur par défaut en utilisant models.SET_DEFAULT,

    • supprimer l'objet Listing en utilisant models.CASCADE,

    • et d'autres paramètres plus complexes que vous pouvez trouver décrits dans la documentation de Django.

Nous ne voulons pas supprimer l'objet Listing si un Band est supprimé, nous utiliserons donc SET_NULL.

Ensuite, nous devons nous assurer que les modifications de notre modèle sont reflétées dans la base de données. Générons donc une migration avec python manage.py makemigrations et exécutons ensuite cette migration avec python manage.py migrate.

Manipulez les clés étrangères dans l'administration de Django

Démarrez le serveur de développement et regardez la vue Create pour l'objet Listing.

Sous l'option Listes, les objets Bandes et listes apparaissent.
L'objet Listing.

Nous avons maintenant une liste déroulante dans laquelle nous pouvons choisir un groupe auquel associer cette liste. La valeur de la liste déroulante est donnée par la représentation en chaîne de l'objet Band.

Définissons le champ band de cette liste à De La Soul. Voyons ensuite ce qu'il en est dans la vue en liste. 

Le champ Band comprend un menu déroulant contenant les options De La Soul, Cut Copy et Foo Fighters.
Une liste déroulante.

Est-il possible de voir les groupes liés pour chacune de ces annonces également ?

Faisons cela en ajoutant le champ band au ListingAdmin dans admin.py.

class ListingAdmin(admin.ModelAdmin):
list_display = ('title', 'band')  # ajouter ‘band' ici

Regardons à nouveau.

La page affiche une seule liste, Gig Tickets, sans aucune autre information.
Une liste de « Billets de concert ».

Joli ! Ce que nous voyons dans la colonne Band est dicté par la représentation en chaîne de l'objet Band, que nous avons configuré plus tôt avec la méthode __str__.

Rafraîchissez vos nouvelles compétences en suivant les étapes du screencast.

En résumé

  • Nous pouvons créer des relations one-to-many en utilisant le champForeignKey.

  • Nous contrôlons la stratégie de ce qui se passe lorsqu'un modèle lié est supprimé, en utilisant l'argument on_delete.

  • Les relations one-to-many peuvent être gérées dans l'administration de Django.

Maintenant que vous pouvez relier différents modèles à l'aide de clés étrangères, il est temps d'examiner comment faire marche arrière et fusionner des migrations.

Exemple de certificat de réussite
Exemple de certificat de réussite