Sélectionnez un sous-ensemble de colonnes
Pour sélectionner uniquement les colonnes sélectionnées dans le modèle, vous pouvez utiliser la fonction suivante.
-
fields(columns: Union[List, str, set, dict]) -> QuerySet
-
exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet
-
Query Set Agent pour
QuerysetProxy.fields(columns: Union[List, str, set, dict]) Méthode
QuerysetProxy.exclude_fields(columns: Union[List, str, set, dict]) Méthode
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.
Notez que fields() et except_fields() fonctionnent à la fois pour le modèle principal (sur des requêtes normales telles que get, all, etc.) et pour les modèles select_lated et prefetch_lated (en utilisant la notation imbriquée).
Donnez des exemples de données comme 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
from tests.settings import DATABASE_URL
base_ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL, force_rollback=True),
metadata=sqlalchemy.MetaData(),
)
class Company(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="companies")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
founded: int = ormar.Integer(nullable=True)
class Car(ormar.Model):
ormar_config = base_ormar_config.copy()
id: int = ormar.Integer(primary_key=True)
manufacturer = ormar.ForeignKey(Company)
name: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
gearbox_type: str = ormar.String(max_length=20, nullable=True)
gears: int = ormar.Integer(nullable=True)
aircon_type: str = ormar.String(max_length=20, nullable=True)
@create_drop_database(base_config=base_ormar_config)
async def sample_data():
# build some sample data
toyota = await Company.objects.create(name="Toyota", founded=1937)
await Car.objects.create(
manufacturer=toyota,
name="Corolla",
year=2020,
gearbox_type="Manual",
gears=5,
aircon_type="Manual",
)
await Car.objects.create(
manufacturer=toyota,
name="Yaris",
year=2019,
gearbox_type="Manual",
gears=5,
aircon_type="Manual",
)
await Car.objects.create(
manufacturer=toyota,
name="Supreme",
year=2020,
gearbox_type="Auto",
gears=6,
aircon_type="Auto",
)
asyncio.run(sample_data())
|
Vous pouvez choisir que le champ spécifié str, List[str], Set[str] or dict a une définition imbriquée en en passant un.
Pour inclure le modèle associé, utilisez le symbole {related_name}__{column}[__{optional_next} etc.].
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | all_cars = await (
Car.objects
.select_related ('fabricant ')
.fields(['id', 'nom',' fabricant__nom'])
. tout ()
)
Pour les voitures dans toutes les voitures:
#colonnes exclues donneront None
assert all(getattr(car, x) est None pour x dans ['year', 'gearbox_type', 'gears', 'aircon_type'])
#colonne incluse sur les modèles relatifs sera disponible, pk colonne est toujours incluse
#même si vous ne l'incluez pas dans la liste des champs
assert car.manufacturer.name =="Toyota"
#aussi dans les modèles nested related-vous ne pouvez pas exclure pk -il est toujours auto ajouté
assert car. manufacturier.founded is None
|
fields() peut être appelé plusieurs fois pour construire la colonne à sélectionner.
Si vous incluez des modèles associés dans l'appel select_lated(), mais que vous ne spécifiez pas de colonne pour ces modèles dans le champ
-
Cela signifie une liste de tous les champs de ces modèles imbriqués.
all_cars = await (
Car.objects
.select_related ('fabricant ')
.fields('id')
.fields(nom))
. tout ()
)
Tous les champs du modèle d'entreprise sont sélectionnés
assert all_cars[0]. manufacturer.name =="Toyota"
assert all_cars[0]. manufacturier.founded == 1937
!!! Warning ne peut pas exclure un champ obligatoire car il lève une ValidationError et pour exclure un champ, il doit être vide.
| La méthode `values()` peut être utilisée pour exclure les champs mandibulaires, tant de données seront utilisées
Soyez récupéré comme un `dict`.
|
Vous ne pouvez pas exclure une colonne de modèle obligatoire-le nom du fabricant__dans cet exemple.
| Avait-elle (
Car.objects
.select_related ('fabricant ')
.fields(['id', 'nom',' fabricant__found'])
. tout ()
)
# will raise pydantic ValidationError comme company.name est requis
|
!!!Une colonne tip Pk ne peut pas être exclue-elle est toujours ajoutée automatiquement, même si elle n'est pas explicitement incluse.
Vous pouvez également passer des champs à inclure en tant que dictionnaire ou ensemble.
Pour marquer un champ comme inclus dans le dictionnaire, utilisez son nom comme clé et les ellipses comme valeur.
Pour parcourir un modèle imbriqué, utilisez un dictionnaire imbriqué.
Pour inclure les champs du dernier niveau au lieu d'un dictionnaire imbriqué, vous pouvez utiliser une collection.
Pour inclure l'ensemble du modèle imbriqué, spécifiez les noms des champs et les ellipses associés au modèle.
Vous pouvez voir un exemple d'équivalence ci-dessous:
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 | # 1. comme dans l'exemple ci-dessus
Avait-elle (
Car.objects
.select_related ('fabricant ')
.fields(['id', 'nom',' fabricant__nom'])
. tout ()
)
# 2. pour marquer un champ comme requis par l'utilisation de l'ellipsis
await (
Car.objects
.select_related ('fabricant ')
.fields("id": ...,
« Name »:...,
Fabricant: {
« Name »:...
}
})
. tout ()
)
# 3. pour inclure le modèle entier nested utilisant ellipsis
await (
Car.objects
.select_related ('fabricant ')
.fields("id": ...,
« Name »:...,
Fabricant: ...
})
. tout ()
)
# 4. pour spécifier les champs au dernier niveau de naissance
#Vous pouvez aussi utiliser Set - Equivalent à 2. ci-dessus
await (
Car.objects
.select_related ('fabricant ')
.fields("id": ...,
« Name »:...,
"Fabricant": {'name'}
})
. tout ()
)
# 5. de course ensemble peut avoir plusieurs champs
Avait-elle (
Car.objects
.select_related ('fabricant ')
.fields("id": ...,
« Name »:...,
"Fabricant": {'name', 'founded'}
})
. tout ()
)
# 6. vous pouvez inclure tous les champs nested,
#Mais il sera égal à 3. au-dessus de qui est le corbeau
await (
Car.objects
.select_related ('fabricant ')
.fields("id": ...,
« Name': ...,
« Fabricant »: {'id', 'name', 'founded'}
})
. tout ()
)
|
Remarque
Ainsi, les opérations comme filter(),select_related(),limit() et offset() etc. peuvent être enchaînées.
Quelque chose comme Track.objects.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()
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.
C'est l'inverse de la méthode fields(), alors consultez la documentation ci-dessus pour connaître les options disponibles.
En particulier, vérifiez ci-dessus comment les dictionnaires et les collections imbriqués sont passés comme masques pour exclure les champs de la hiérarchie entière.
Notez que fields() et except_fields() fonctionnent à la fois pour le modèle principal (sur des requêtes normales telles que get, all, etc.) et pour les modèles select_lated et prefetch_lated (en utilisant la notation imbriquée).
Vous pouvez trouver quelques exemples simples ci-dessous:
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
from tests.settings import DATABASE_URL
base_ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL, force_rollback=True),
metadata=sqlalchemy.MetaData(),
)
class Company(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="companies")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
founded: int = ormar.Integer(nullable=True)
class Car(ormar.Model):
ormar_config = base_ormar_config.copy()
id: int = ormar.Integer(primary_key=True)
manufacturer = ormar.ForeignKey(Company)
name: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
gearbox_type: str = ormar.String(max_length=20, nullable=True)
gears: int = ormar.Integer(nullable=True)
aircon_type: str = ormar.String(max_length=20, nullable=True)
@create_drop_database(base_config=base_ormar_config)
async def sample_data():
# build some sample data
toyota = await Company.objects.create(name="Toyota", founded=1937)
await Car.objects.create(
manufacturer=toyota,
name="Corolla",
year=2020,
gearbox_type="Manual",
gears=5,
aircon_type="Manual",
)
await Car.objects.create(
manufacturer=toyota,
name="Yaris",
year=2019,
gearbox_type="Manual",
gears=5,
aircon_type="Manual",
)
await Car.objects.create(
manufacturer=toyota,
name="Supreme",
year=2020,
gearbox_type="Auto",
gears=6,
aircon_type="Auto",
)
asyncio.run(sample_data())
# select manufacturer but only name,
# to include related models use notation {model_name}__{column}
all_cars = await (
Car.objects
.select_related('manufacturer')
.exclude_fields([
'year',
'gearbox_type',
'gears',
'aircon_type',
'company__founded'
])
.all()
)
for car in all_cars:
# excluded columns will yield None
assert all(getattr(car, x) is None
for x in [
'year',
'gearbox_type',
'gears',
'aircon_type'
])
# included column on related models will be available,
# pk column is always included
# even if you do not include it in fields list
assert car.manufacturer.name == 'Toyota'
# also in the nested related models,
# you cannot exclude pk - it's always auto added
assert car.manufacturer.founded is None
# fields() can be called several times,
# building up the columns to select
# models included in select_related
# but with no columns in fields list implies all fields
all_cars = await (
Car.objects
.select_related('manufacturer')
.exclude_fields('year')
.exclude_fields(['gear', 'gearbox_type'])
.all()
)
# all fields from company model are selected
assert all_cars[0].manufacturer.name == 'Toyota'
assert all_cars[0].manufacturer.founded == 1937
# cannot exclude mandatory model columns,
# company__name in this example - note usage of dict/set this time
await (
Car.objects
.select_related('manufacturer')
.exclude_fields([{'company': {'name'}}])
.all()
)
# will raise pydantic ValidationError as company.name is required
|
!!!Avertissement Un champ obligatoire ne peut pas être exclu car il lève une ValidationError et pour exclure un champ, il doit pouvoir être vide.
| La méthode `values()` peut être utilisée pour exclure les champs manditaires, tant de données seront utilisées
Soyez retourné comme un `dict`.
|
!!! Indice La colonne Pk ne peut pas être exclue-elle est toujours ajoutée automatiquement même si elle est explicitement exclue.
Remarque
Ainsi, les opérations comme filter(),select_related(),limit() et offset() etc. peuvent être enchaînées.
Quelque chose comme Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()
La méthode QuerysetProxy
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.
Le domaine
Exactement la même fonctionnalité que les champs ci-dessus, mais vous permet de sélectionner une colonne parmi les objets associés à l'autre extrémité de la relation.
!!!conseil Pour en savoir plus sur Querysetproxy, visitez la section Querysetproxy
Exclure les champs
Exactement comme la fonction except_fields ci-dessus, mais vous permet de sélectionner une colonne parmi les objets associés à l'autre extrémité de la relation.
!!!conseil Pour en savoir plus sur Querysetproxy, visitez la section Querysetproxy