Aller au contenu

Relation avec

Actuellement, Ormar prend en charge deux types de relations:

  • Un à plusieurs (et plusieurs à un) avec le champ foreignkey
  • Plusieurs à plusieurs avec un champ ManyToMany

Vous trouverez ci-dessous un exemple de définition très basique de chaque relation.

Pour en savoir plus sur les méthodes, les possibilités, les définitions, etc., lisez les sections suivantes du document.

Clés étrangères

Pour définir une relation plusieurs-à-un, utilisez un champ de clé étrangère.

 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
from typing import Dict, Optional, Union

import databases
import ormar
import sqlalchemy

DATABASE_URL = "sqlite:///test.db"

ormar_base_config = ormar.OrmarConfig(
    database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)


class Department(ormar.Model):
    ormar_config = ormar_base_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)


class Course(ormar.Model):
    ormar_config = ormar_base_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    department: Optional[Union[Department, Dict]] = ormar.ForeignKey(Department)

!!! Astuce Pour en savoir plus sur les relations un à plusieurs, visitez la section Clés étrangères

Clé étrangère inversée

La définition d'une relation un-à-plusieurs utilise également ForeignKey, qui s'inscrit automatiquement pour vous.

Donc, en ce qui concerne l'exemple ci-dessus.

1
2
3
4
5
6
7
8
Département de classe (modèle d'ordre):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    nom: str = ormar.String(max_length=100)
    #Il y a un champ virtuel ici comme des follows
    courses: Optional[List[Course]] = ormar.ForeignKey(Course, virtuel =True)
    # note que vous ne le définissez pas pour vous-même, l'ordre le fait pour vous.

!!!Conseil Pour en savoir plus sur les relations plusieurs-à-un (c'est-à-dire pour modifier le nom du champ généré), visitez la section Clés étrangères

!!!La tip ReverseforeignKey vous permet d'interroger des modèles pertinents avec Queryset-proxy.

1
Il vous permet d'utiliser `await department.courses.all()` pour féliciter les données liées uniquement au département spécifique etc.

Plusieurs à plusieurs

Pour définir une relation plusieurs à plusieurs, utilisez le champ ManyToMany.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Catégorie de classe (modèle ormar):
    ormar_config = ormar.OrmarConfig(
        database=database,
        Metadata=Metadata,
        tablename="catégories"
    )

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=40)

Classe Post(modèle ormar):
    ormar_config = ormar.ormarConfig(
        database=database,
        Metadata=Metadata,
    )

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    Catégories: Optional[List[Category]] = ormar.ManyToMany(Category)

!!! Astuce Pour en savoir plus sur les relations plusieurs-à-plusieurs, visitez la section plusieurs-à-plusieurs

!!!tip ManyToMany vous permet d'interroger des modèles pertinents avec Queryset-proxy.

1
Cela vous permet d'utiliser `await post.categories.all()` mais aussi `await category.posts.all()` pour féliciter les données relatives uniquement à des articles spécifiques, catégorie etc.

A travers les champs

Dans le cadre de la relation ManyToMany, vous pouvez définir un modèle de passage direct qui peut contenir des champs supplémentaires qui peuvent être utilisés pour le filtrage, le tri, etc. Les champs définis de cette manière seront exposés sur le revers de la requête actuelle du modèle m2m.

Ainsi, si une requête est effectuée à partir du modèle A vers le modèle B, seul le modèle B expose le champ through. Lequel a du sens, car il s'agit d'un modèle/champ unidirectionnel pour chaque modèle pertinent.

 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
Catégorie de classe (modèle ormar):
    ormar_config = ormar.OrmarConfig(
        database=database,
        Metadata=Metadata,
        tablename="catégories"
    )

    id = ormar.Integer(primary_key=True)
    name = ormar.String(max_length=40)

# You can specify additional fields sur le modèle
Classe PostCategory(modèle ormar):
    ormar_config = ormar.OrmarConfig(
        database=database,
        Metadata=Metadata,
        tablename="posts_x_categories",
    )

    id: int = ormar.Integer(primary_key=True)
    sort_order: int = ormar.Integer(nullable=True)
    param_name: str = ormar.String(default="Name", max_length=200)


Classe Post(modèle ormar):
    ormar_config = ormar.ormarConfig(
        database=database,
        Metadata=Metadata,
    )

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    Catégories = ormar.ManyToMany(Catégorie, through=PostCategory)

!!!tip Pour en savoir plus sur les relations plusieurs-à-plusieurs et les champs, visitez la section plusieurs-à-plusieurs

!!!tip ManyToMany vous permet d'interroger des modèles pertinents avec Queryset-proxy.

1
Cela vous permet d'utiliser `await post.categories.all()` Mais aussi `await category.posts.all()` Pour les données relatives uniquement aux articles spécifiques, catégorie etc.

Ordre de tri par défaut des relations

Par défaut, les relations suivent l'ordre de tri par défaut du modèle, de sorte que la colonne Primary_key est ascendante, ou tout ordre de tri dans l'objet ormar_config.

!!! Astuce Pour en savoir plus sur l'ordre de tri des modèles, visitez la section Modèles de la documentation

Mais vous pouvez modifier l'ordre dans lequel les modèles associés sont chargés pendant une requête en fournissant les paramètres orders_by et related_orders_by à la relation.

Dans une relation, vous ne pouvez trier que par colonnes de modèle directement liées ou, pour les colonnes plusieurs à plusieurs, par colonnes de modèle {through_field_name}__{column_name}

Un exemple de configuration peut ressembler à ceci:

 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
databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()


base_ormar_config = ormar.OrmarConfig(
    database=database,
    Metadata=Metadata,
)


Auteur de classe (modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    nom: str = ormar.String(max_length=100)


Classe Book(modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    author: Optional[Author] = ormar.ForeignKey(
        Auteur, orders_by=["nom"], related_orders_by=["-année"]
    )
    title: str = ormar.String(max_length=100)
    année: int = ormar.Integer(nullable=True)
    ranking: int = ormar.Integer(nullable=True)

Appelez maintenant:

await Author.objects.select_related("books").get() - Les livres seront triés par ordre décroissant par année de livre

await Book.objects.select_related("author").all() - Les auteurs seront triés par ordre croissant de nom d'auteur

Auto-référencement et référencement différé

Pour créer une relation automatique ou créer deux modèles qui se réfèrent l'un à l'autre dans au moins deux relations différentes (rappelez-vous que le revers est automatiquement enregistré pour vous), vous devez utiliser ForwardRef dans le module d'entrée.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
PersonRef = ForwardRef("Personne")


Classe Person(modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    superviseur: PersonRef = ormar.ForeignKey(PersonRef, related_name="employés")


Person.update_forward_refs()

!!! Astuce Pour en savoir plus sur l'auto-référencement et les relations différées, visitez la section Commentaires différés