Aller au contenu

Query Set Agent pour

Lorsque vous accédez directement au champ ManyToMany associé, ainsi qu'à la clé ReverseForeignKey, une liste des modèles associés est renvoyée.

Mais en même temps, il expose un sous-ensemble de l'API QuerySet, de sorte que vous pouvez filtrer, créer, sélectionner des modèles pertinents, etc. directement à partir du modèle parent.

!!!Remarque Par défaut, les QuerySet exposés ont été filtrés pour renvoyer uniquement les modèles associés au modèle parent.

1
Donc, si vous posez des questions `post.categories.all()`, vous obtiendrez toutes les catégories liées à cet article, pas toutes à la table.

!!!Notez que lorsque vous accédez à la méthode QuerySet API via QuerysetProxy, vous n'avez pas besoin d'utiliser les propriétés de l'objet comme vous le feriez pour une requête normale.

1
2
3
Donc, note que c'est `post.categories.all()` et**pas** `post.categories.objects.all()`.

Pour en savoir plus sur les méthodes disponibles QuerySet visiter [queries][queries]

!!!Avertissement La requête d'un modèle associé à partir de ManyToMany efface la liste des modèles associés chargés sur le modèle parent:

1
2
3
4
5
6
7
8
9
Exemple:`post.categories.first()` mettra en place des articles. catégories à la liste de 1 modèle relationné-> l'un a été récupéré par premier ()

Exemple 2: si le post a 4 catégories donc `len(post.categories) == 4` appelle `post.categories.limit(2).all()`
-> chargera seulement 2 enfants et maintenant `assert len(post.categories) == 2`

Ce happen pour toutes les méthodes QuerysetProxy récupère les données:`get`,`all` et `first` et dans `get_or_create` si le modèle existe déjà.

Note que la valeur a été récupérée par `create` Ou créé dans `get_or_create` et `update_or_create`
Si le modèle n'existe pas, il sera ajouté à la liste des relations (pas clair).

Lire les données de la base de données

obtenir

get(**kwargs): -> Modèle

Pour obtenir uniquement l'un des modèles pertinents filtrés par nom, vous pouvez utiliser get(**kwargs) méthode.

1
2
3
4
5
6
7
8
9
# Grab une catégorie
assert news == await post.categories.get(name="News")

# note que la méthode retourne à la catégorie afin que vous puissiez obtenir cette valeur
#mais c'est aussi une liste de modifications des modèles liés en place
# So regardless de ce qui était précédemment loadé sur le modèle parent
# now it has only one value -> juste chargé avec get() call
assert len(post. catégories) == 1
assert post.categories[0] == news

Tip

Obtenir ou créer

get_or_create(_defaults: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Model, bool]

Essayez d'obtenir une ligne qui répond aux critères, et si une exception NoMatch est levée, une nouvelle ligne est créée avec les kwargs et_defaults donnés.

!!!tip En savoir plus dans le document de requête get_or_create

Tous les

all(**kwargs) -> List[Optional["Model"]]

Pour obtenir une liste des modèles pertinents, utilisez la méthode all().

Notez que vous pouvez filtrer les ensembles de requêtes, sélectionner des relations, exclure des champs, etc. comme une requête normale.

1
2
3
4
5
6
7
#avec toutes les méthodes Queryset- filtering, selecting columns, counting etc.
await news.posts.filter(title__contains="M2M").all()
await Category.objects.filter(posts__author=guido).get()

# Columns modèles de beaucoup à beaucoup de relations peuvent être préfabriqués
news_posts = await news.posts.select_related("author").all()
assert news_posts[0].author == guido

Tip

itération

iterate(**kwargs) -> AsyncGenerator["Model"]

Pour itérer sur un modèle pertinent, utilisez la méthode iterate().

Notez que vous pouvez filtrer les ensembles de requêtes, sélectionner des relations, exclure des champs, etc. comme une requête normale.

1
2
3
#Iterate sur les catégories de ce post avec un générateur async
async for category in post.categories.iterate():
    print(nom de la catégorie)

Tip

Insérer/mettre à jour des données dans une base de données

Créer des

Création (**kwargs): -> Modèle

Créer un modèle associé directement à partir du modèle parent.

Les tables liées, ainsi que les ID de relation dans la base de données, sont automatiquement remplis.

1
2
3
4
#Créer des objets de colonnes à partir de l'instance:
await post.categories.create(nom ="Conseils")
assert len(await post.categories.all()) == 2
# newly created instance a déjà une relation persistante dans la base de données

Tip

Pour les relations plusieurs-à-plusieurs, si vous avez déclaré des champs supplémentaires sur le modèle de passage explicitement fourni, il existe une fonctionnalité supplémentaire pour passer des paramètres qui sera utilisée pour créer le modèle de passage.

Étant donné un tel échantillon:

 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
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 Category(ormar.Model):
    ormar_config = ormar_base_config.copy(tablename="categories")

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


class PostCategory(ormar.Model):
    ormar_config = ormar_base_config.copy(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)


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

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    categories = ormar.ManyToMany(Category, through=PostCategory)

Vous pouvez remplir un champ via le modèle dans un appel create() de la manière suivante:

1
2
3
4
5
6
7
post = await Post(title="Test post").save()
await post. catégories.create(
    name="Test category1",
    #dans arguments passer un dictionnaire avec le nom du champ et les clés
    #Correspondance à travers les champs de modèles
    postcategory={"sort_order": 1, "param_name": "volume"},
)

Obtenir ou créer

get_or_create(_defaults: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Model, bool]

Essayez d'obtenir une ligne qui répond aux critères, et si une exception NoMatch est levée, une nouvelle ligne est créée avec les kwargs donnés.

!!!tip En savoir plus dans le document de requête get_or_create

Mettre à jour ou créer

update_or_create(**kwargs) -> Model

Mettez à jour le modèle ou créez un nouveau modèle s'il n'y a pas de correspondance dans la base de données.

!!!tip En savoir plus dans le document de requête update_or_create

Actualités

update(**kwargs, each:bool = False) -> int

Mettez à jour le modèle associé avec les paramètres de mots-clés fournis, renvoyant le nombre de lignes mises à jour.

Tip

Notez que pour les mises à jour relationnelles plusieurs-à-plusieurs, vous pouvez également accepter des paramètres avec des noms de champs et des dictionnaires de champs.

 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
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 Category(ormar.Model):
    ormar_config = ormar_base_config.copy(tablename="categories")

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


class PostCategory(ormar.Model):
    ormar_config = ormar_base_config.copy(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)


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

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    categories = ormar.ManyToMany(Category, through=PostCategory)

Dans l'exemple ci-dessus, vous pouvez mettre à jour les propriétés de postcategory dans l'appel suivant:

1
2
3
await post.categories.filter(nom ="Test category3").update(
            Postcategory= Catégorie{"sort_order": 4}
        )

Filtrer et trier

Filtré par

filter(*args, **kwargs) -> QuerySet

Vous permet de filtrer par n'importe quel attribut/champ de modèle et d'obtenir des instances à l'aide de filtres sur les relations FK.

Tip

Exclusion de

exclude(*args, **kwargs) -> QuerySet

Fonctionne exactement de la même manière que le filtre, et tous les modificateurs (suffixes) sont les mêmes, mais renvoie la condition not.

Tip

Base de l'ordre

order_by(columns:Union[List, str]) -> QuerySet

Avec order_by(), vous pouvez trier les résultats de la base de données en fonction des champs que vous avez sélectionnés.

!!!tip En savoir plus dans le document de requête order_by

Connexions et sous-requêtes

select_related(related: Union[List, str]) -> QuerySet

Permet de pré-récupérer les modèles pertinents au cours de la même requête.

Avec select_lated, une seule requête est toujours exécutée sur la base de données, ce qui signifie qu 'une connexion (parfois complexe) est générée et que les modèles imbriqués ultérieurs sont traités en python.

!!!tip En savoir plus sur select_lated dans le document de requête

prefetch_related(related: Union[List, str]) -> QuerySet

Permet de pré-récupérer les modèles pertinents lors d'une requête-mais contrairement à select_lated, chaque modèle suivant est récupéré dans une requête de base de données distincte.

Lorsque vous utilisez prefetch_lated, chaque modèle exécute une requête sur la base de données, ce qui signifie que vous exécutez plusieurs requêtes l'une après l'autre.

!!!tip En savoir plus dans le document de requête prefetch_lated

Pagination et nombre de lignes

pagination

paginate(page: int, page_size: int = 20) -> QuerySet

Une combinaison de méthodes de décalage et de restriction basées sur le numéro de page et la taille est disponible.

Limitation des limites

limit(limit_count: int) -> QuerySet

Vous pouvez limiter les résultats au nombre de modèles parents dont vous avez besoin.

Tip

compensation

offset(offset: int) -> QuerySet

Vous pouvez compenser les résultats par le nombre de modèles principaux que vous souhaitez.

Tip

Sélectionnez un sous-ensemble de colonnes

Le domaine

fields(columns: Union[List, str, set, dict]) -> QuerySet

Avec fields(), vous pouvez sélectionner un sous-ensemble des colonnes du modèle pour limiter la charge de données.

Tip

Exclure les champs

exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet

Avec except_fields(), vous pouvez sélectionner un sous-ensemble des colonnes du modèle qui seront exclues pour limiter le chargement des données.

!!!tip En savoir plus dans le document de requête except_fields

Fonctions agrégées

Compter les

count(distinct: bool = True) -> int

Renvoie le nombre de lignes correspondant à une condition donnée (c'est-à-dire applique des filtres et exclusions)

Tip

Existence de

Existence () -> valeurs booléennes

Renvoie une valeur booléenne pour confirmer qu 'il y a des lignes qui répondent à un critère donné (appliqué avec des filtres et des exclusions)

Tip