Ga naar inhoud

relatie

Ormar ondersteunt momenteel twee soorten relaties:

  • Een-op-veel (en veel-op-een) met vreemde velden
  • Veel-op-veel met ManyToMany velden

Hieronder vindt u voorbeelden van zeer basisdefinities van elke relatie.

Lees de volgende secties van de documentatie voor meer informatie over methoden, mogelijkheden, definities, enz.

buitenlandse sleutel

Gebruik een veld met een vreemde sleutel om een veel-op-één-relatie te definiëren.

 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)

Tips

omgekeerde buitenlandse sleutel

De definitie van een één-op-veel-relatie maakt ook gebruik van ForeignKey, dat u automatisch registreert.

Daarom in het geval van het bovenstaande voorbeeld.

1
2
3
4
5
6
7
8
Klasse Afdeling (ormar. Model):
    ormar _ config = basis _ ormar _ config kopie ()

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Naam: str = ormar. String (max _ length = 100)
    # er is hier een virtueel veld zoals volgt
    Cursussen: Optioneel [Lijst [Cursus]] = ormar. ForeignKey (Cursus, virtueel = Waar)
    # let op dat je het NIET zelf definieert, ormar doet het voor je.

!!!Tip Ga naar de sectie Buitenlandse sleutels voor meer informatie over veel-op-één-relaties (d.w.z. het wijzigen van de naam van een gegenereerd veld)

!!!Met Tip ReverseforeignKey kunt u gerelateerde modellen opvragen met queryset-proxy.

1
Hiermee kunt u `await department.courses.all()` gebruiken om gegevens op te halen die alleen betrekking hebben op specifieke afdelingen enz.

# veel te veel

Gebruik het veld ManyToMany om een veel-op-veel-relatie te definiëren.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Klasse Categorie (ormar. Model):
    ormar _ config = ormar. OrmarConfig (
        Database = databank,
        metagegevens = metagegevens;
        Tablename = "categorieën",
    )

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Naam: str = ormar. String (max _ length = 40)

Klasse Post (ormar. Model):
    ormar _ config = ormar. OrmarConfig (
        Database = databank,
        metagegevens = metagegevens;
    )

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Titel: str = ormar. String (max _ length = 200)
    Categorieën: Optioneel [Lijst [Categorie]] = ormar. ManyToMany (Categorie)

Tips

!!!Met Tip ManyToMany kunt u gerelateerde modellen opvragen met queryset-proxy.

1
Hiermee kunt u `await post.categories.all()` maar ook `await category.posts.all()` gebruiken om gegevens op te halen die alleen betrekking hebben op specifieke berichten, categorieën enz.

Door de velden

Als onderdeel van de ManyToMany-relatie kunt u een pass-through-model definiëren dat extra velden kan bevatten die kunnen worden gebruikt voor filteren, sorteren, enz. Velden die zo zijn gedefinieerd, worden weergegeven aan de achterkant van de huidige query in het m2m-model.

Daarom, als u van model A naar model B vraagt, legt alleen model B het doorlopende veld bloot. Wat logisch is omdat het een eenrichtingsmodel / veld is voor elk gerelateerd model.

 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
Klasse Categorie (ormar. Model):
    ormar _ config = ormar. OrmarConfig (
        Database = databank,
        metagegevens = metagegevens;
        Tablename = "categorieën",
    )

    Id = ormar. Geheel getal (primaire _ sleutel = Waar)
    Naam = ormar. String (max _ lengte = 40)

# u kunt aanvullende velden opgeven op via modellen
Klasse PostCategorie (ormar. Model):
    ormar _ config = ormar. OrmarConfig (
        Database = databank,
        metagegevens = metagegevens;
        Tablename = "berichten _ x _ categorieën",
    )

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    sorteer _ volgorde: int = ormar. Geheel getal (nullable = Waar)
    param _ name: str = ormar. String (standaard = "Naam", max _ length = 200)


Klasse Post (ormar. Model):
    ormar _ config = ormar. OrmarConfig (
        Database = databank,
        metagegevens = metagegevens;
    )

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Titel: str = ormar. String (max _ length = 200)
    Categorieën = ormar. ManyToMany (Categorie, through=PostCategory)

Tip

!!!Met Tip ManyToMany kunt u gerelateerde modellen opvragen met queryset-proxy.

1
Hiermee kunt u `await post.categories.all()` maar ook `await category.posts.all()` gebruiken om gegevens op te halen die alleen betrekking hebben op specifieke berichten, categorieën enz.

Standaard sorteervolgorde relatie

Standaard volgen relaties de standaardsorteervolgorde van het model, dus primaire\ _ sleutelkolommen staan in oplopende volgorde, of ormar\ _ config elke sorteervolgorde in het object.

Tip

U kunt echter de volgorde wijzigen waarin gerelateerde modellen worden geladen tijdens een query door de relatie met de orders\ _ by en gerelateerde\ _ orders\ _ by parameters op te geven.

In een relatie kunt u alleen sorteren op direct gerelateerde modelkolommen, of voor veel-op-veel kolommen kunt u ook sorteren op modelkolommen {through_field_name}__{column_name}

Een voorbeeldconfiguratie zou er als volgt uit kunnen zien:

 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
Database = databanken. Database (DATABASE _ URL)
Metagegevens = sqlalchemie. MetaData ()


basis _ ormar _ config = ormar. OrmarConfig (
    Database = databank,
    metagegevens = metagegevens;
)


Klasse Auteur (ormar. Model):
    ormar _ config = basis _ ormar _ config kopie ()

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Naam: str = ormar. String (max _ length = 100)


Klassenboek (ormar. Model):
    ormar _ config = basis _ ormar _ config kopie ()

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Auteur: Optioneel [Auteur] = ormar. ForeignKey (
        Auteur, orders _ door = ["naam"], gerelateerde _ orders _ door = ["-jaar"]
    )
    Titel: str = ormar. String (max _ length = 100)
    Jaar: int = ormar. Geheel (nullable = Waar)
    Ranglijst: int = ormar. Geheel (nullable = Waar)

Bel nu:

await Author.objects.select_related("books").get() Boeken worden gesorteerd op boekjaar in aflopende volgorde

await Book.objects.select_related("author").all() Auteurs worden gesorteerd op auteursnaam in oplopende volgorde

Zelfreferentie en uitgestelde referentie

Om een automatische relatie te creëren of om twee modellen te maken die naar elkaar verwijzen in ten minste twee verschillende relaties (onthoud dat het omgekeerde automatisch voor u wordt geregistreerd), moet u ForwardRef gebruiken in de invoermodule.

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


Klasse Persoon (ormar. Model):
    ormar _ config = basis _ ormar _ config kopie ()

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Naam: str = ormar. String (max _ length = 100)
    Supervisor: PersonRef = ormar. ForeignKey (PersonRef, gerelateerde _ naam = "werknemers")


Persoon. update _ forward _ refs ()

Tips