Zum Inhalt

Auswahl der Teilmengen .

Um nur die Spalten auszuwählen , die im Modell ausgewählt sind , können Sie die folgenden Funktionen verwenden .

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

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

  • Frage an den Gruppenleiter

    • QuerysetProxy.fields(columns: Union[List, str, set, dict]) Die Methode
    • QuerysetProxy.exclude_fields(columns: Union[List, str, set, dict]) Die Methode

Bereichen

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

Mit fields () können Sie eine Teilmenge der Modellspalte auswählen , um die Datenlast zu begrenzen .

Beachten Sie , dass fields () und except \ _ fields () sowohl für das Hauptmodell (in allgemeinen Abfragen wie get , all usw .) als auch für die select \ _ lated - und prefetch \ _ lated-Modelle (mit verschachtelten Notationen) gelten .

Folgende Beispieldaten sind angegeben :

 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())

Sie können ein bestimmtes Feld auswählen , das eine geschachtelte Definition hat , indem Sie eine übergeben str, List[str], Set[str] or dict.

Um verwandte Modelle einzubeziehen , verwenden Sie das Symbol {related_name}__{column}[__{optional_next} etc.].

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Die Zahl der Wörter = (
    Car.objects
    . select _ related ('manufacturer') (auf Englisch)
    . fields (VMware ' id', ' name', ' manufacturer _ _ name')
    Das All ()
)
für alle Autos in allen Autos :
    Excluded columns will keine einzige
    assert all (getattr (car , x) is None for x in VIA ' year ' , ' gearbox _ type', ' gears', ' aircon _ type']) (nicht verfügbar)
    # included column on related models will be available , pk column is always included
    # auch wenn du es nicht in die fields list include
    Assert hinzufügencar.manufacturer.name= = Toyota oder Toyota
    # also in den nested related models - Sie können PK nicht ausblenden - es ist immer mit dem Auto hinzugefügt
    Hersteller , Hersteller , Founded is None

fields () kann mehrmals aufgerufen werden , um die Spalten zu erzeugen , die ausgewählt werden sollen .

Wenn Sie verwandte Modelle in den Aufruf select \ _ lated () aufnehmen , aber keine Spalten für diese Modelle in den Feldern angeben

  • Bezeichnet eine Liste aller Felder dieser verschachtelten Modelle .

    Die Zahl der Wörter = ( Car.objects . select _ related ('manufacturer') (auf Englisch) . fields ('id ') Bearbeiten . fields („ Name " von VIRTINO) Das All () ) Alle Felder des Unternehmensmodells sind ausgewählt assert all _ cars [ 0 ] (alle _ Wagen)manufacturer.name= = Toyota oder Toyota assert all _ cars [ 0 ] . manufacturer . founded = 1937 (auf Englisch)

!!! warning kann ein erzwingendes Feld nicht ausschließen , da es einen ValidationError verursachen würde , und das Feld muss leer sein , um es auszuschließen .

1
2
Die `values()`-Methode kann verwendet werden , um mandantenfähige Felder zu excludieren , obwohl die Daten
Lassen Sie sich wie ein `dict` zurückversetzen .

Sie können die obligatorische Modellspalte nicht ausschließen - den Namen des Herstellers __in diesem Beispiel .

1
2
3
4
5
6
7
und dann (
    Car.objects
    . select _ related ('manufacturer ') (auf Englisch)
    . fields (VMware ‚ id', ‚ name', ‚ Hersteller _ _ gegründet ' ])
    Das All ()
)
# wird Pydantische Validierungsfehler verursachencompany.nameerforderlich ist

!!!Eine tip Pk-Spalte kann nicht ausgeschlossen werden - sie wird immer automatisch hinzugefügt , auch wenn sie nicht explizit enthalten ist .

Sie können auch ein Feld übergeben , das als Wörterbuch oder Satz aufgenommen werden soll .

Um ein Feld als in einem Wörterbuch enthalten zu markieren , verwenden Sie dessen Namen als Schlüssel und ein Auslassungszeichen als Wert .

Um verschachtelte Modelle zu durchlaufen , verwenden Sie ein verschachteltes Wörterbuch .

Um Felder der letzten Ebene anstelle eines verschachtelten Wörterbuchs einzubeziehen, können Sie Sammlungen verwenden.

Um das gesamte verschachtelte Modell einzubeziehen, geben Sie die dem Modell zugeordneten Feldnamen und Auslassungsnummern an.

Ein Beispiel für Gleichwertigkeit sehen Sie unten:

 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: Wie im Beispiel oben
und dann (
    Car.objects
    . select_related ('manufacturer')(auf Englisch)
    . fields (VMware 'id',' name','manufacturer__name')
    Das All ()
)

2. Ein Feld markieren, das die Verwendung von Ellipsis erfordert
und dann (
    Car.objects
    . select_related ('manufacturer ')(auf Englisch)
    . fields ('id ':..., oder?)
             „ Vorname ":…
             Hersteller: {
                 Der Name: …
                }
             })
    Das All ()
)

#3: Das gesamte nested Model mit Ellipsis includieren
Abseits (
    Car.objects
    . select_related ('manufacturer')(auf Englisch)
    . fields ('id ':..., oder?)
             „ Vorname ":…
             „ Hersteller ":…
             })
    Das All ()
)

#4: Spezifizieren Sie Ihre Felder auf der letzten Ebene
#you can also use set-äquivalent zu 2
Abseits (
    Car.objects
    . select_related ('manufacturer')(auf Englisch)
    . fields ('id ':..., oder?)
             „ Vorname ":…
             "Hersteller": {'name'}
             })
    Das All ()
)

#5: Ein Kurs-Set kann mehrere Felder haben
Die Frage (
    Car.objects
    . select_related ('manufacturer')(auf Englisch)
    . fields ('id ':..., oder?)
             „ Vorname ":…
             "Hersteller": {'name', 'founded'}
             })
    Das All ()
)

#6 Du kannst alle nested fields einschließen.
Aber es wird gleich sein von 3. Über dem, was kürzer ist
Abseits (
    Car.objects
    . select_related ('manufacturer')(auf Englisch)
    . fields ('id ':..., oder?)
             „ Vorname ":…
             "Hersteller": {'id', 'name', 'founded'}
             })
    Das All ()
)

!!!Beachten Sie, dass alle Methoden, die keine Zeile zurückgeben, explizit eine Instanz von QuerySet zurückgeben, sodass Sie sie miteinander verknüpfen können.

1
2
3
So operations like `filter()`,`select_related()`,`limit()` und `offset()` etc. kann chained werden.

Etwas Ähnliches `Track.objects.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

Ausschlusswort

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

Mit except_fields () können Sie eine Teilmenge der Modellspalten auswählen, die ausgeschlossen werden sollen, um das Laden von Daten zu begrenzen.

Es ist das Gegenteil der fields ()-Methode, also überprüfen Sie die oben genannte Dokumentation, um die verfügbaren Optionen zu sehen.

Insbesondere wird geprüft, wie oben geschachtelte Wörterbücher und Sammlungen als Masken übergeben werden, um Felder von der gesamten Hierarchie auszuschließen.

Beachten Sie, dass fields () und except_fields () sowohl für das Hauptmodell (in allgemeinen Abfragen wie get, all usw.) als auch für die select_lated-und prefetch_lated-Modelle (mit verschachtelten Notationen) gelten.

Unten finden Sie ein paar einfache Beispiele:

  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

!!!Die Warnung kann ein Feld nicht ausschließen, da es einen ValidationError auslöst und leer sein muss, um ein Feld auszuschließen.

1
2
Die `values()`-Methode kann verwendet werden, um mandantenfähige Felder zu schließen, obwohl die Daten
Sie werden als `dict` zurückgegeben.

Hinweis Die Pk-Spalte kann nicht ausgeschlossen werden-sie wird immer automatisch hinzugefügt, auch wenn sie explizit ausgeschlossen wird.

!!!Beachten Sie, dass alle Methoden, die keine Zeile zurückgeben, explizit eine Instanz von QuerySet zurückgeben, sodass Sie sie miteinander verknüpfen können.

1
2
3
So Operationen wie `filter()`,`select_related()`,`limit()` und `offset()` etc. können getrennt werden.

Etwas Ähnliches `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

Die QuerysetProxy Methode

Wenn Sie direkt auf das zugehörige Feld ManyToMany und ReverseForeignKey zugreifen, wird eine Liste der zugehörigen Modelle zurückgegeben.

Gleichzeitig wird jedoch eine Teilmenge der QuerySet-API verfügbar gemacht, sodass Sie relevante Modelle direkt aus dem übergeordneten Modell filtern, erstellen, auswählen usw. können.

Bereich

Die Funktionalität des Felds oben ist identisch, ermöglicht es Ihnen jedoch, die Spalte aus einem verwandten Objekt am anderen Ende der Beziehung auszuwählen.

!!!tip Um mehr über QuerysetProxy zu erfahren, besuchen Sie den Abschnitt querysetproxy

Ausschlusswort

Genau wie die oben genannte except_fields-Funktion, ermöglicht es Ihnen jedoch, Spalten aus verwandten Objekten am anderen Ende der Beziehung auszuwählen.

!!!tip Um mehr über QuerysetProxy zu erfahren, besuchen Sie den Abschnitt querysetproxy