Ga naar inhoud

aanvraag

U kunt het Ormar-model gebruiken in plaats van het Pydantic-model in de FastAPI-verzoeklichaamparameters.

Je kunt ook ormar mengen. Modellen met pydantic indien nodig.

Een van de meest voorkomende taken in een verzoek is het uitsluiten van bepaalde velden die u niet wilt opnemen in de payload die naar de API wordt verzonden.

Dit kan op verschillende manieren worden bereikt in Ormar, dus u kunt hieronder uw opties bekijken en degene kiezen die het beste bij uw situatie past.

Velden uitsluiten van aanvragen

optioneel veld

Houd er rekening mee dat elk optioneel veld niet vereist is, wat betekent dat optionele velden kunnen worden overgeslagen in zowel reacties als verzoeken.

Velden zijn niet vereist als (een / veel / alle) van de volgende situaties optreedt:

  • Veld gemarkeerd als nullable = Waar
  • Veld heeft een standaardwaarde of functionaliteit, d.w.z. standaard = "Test"
  • Veld stelt de standaardwaarde van de server\ _ in
  • -veld is een autoincrement=Trueprimary\ _ sleutelveld (let op ormar. Standaard van de integrale primaire\ _ sleutel is autoincrement)

Voorbeeld:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
basis _ ormar _ config = ormar. OrmarConfig (
    Metagegevens = metagegevens
    Database = database
)

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

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    E-mail: str = ormar. String (max _ length = 255)
    Wachtwoord: str = ormar. String (max _ length = 255)
    voornaam: str = ormar. String (max _ length = 255, nullable = True)
    achternaam: str = ormar. String (max _ length = 255)
    Categorie: str = ormar. String (max _ length = 255, default = "User")

In het bovenstaande voorbeeld kunnen de velden id (dat is een automatisch verhogend geheel getal), voornaam (die nullable = True heeft) en categorie (die een standaardwaarde heeft) optioneel zijn, worden overgeslagen in het antwoord en het model wordt nog steeds gevalideerd.

Als het veld nullable is, hoeft het niet te worden opgenomen in de payload tijdens het maken en in de reactie, dus volgens het bovenstaande voorbeeld kunt u:

!!! Waarschuwing Merk op dat hoewel u geen optionele velden hoeft door te geven, u dit nog steeds kunt doen. Als iemand een waarde doorgeeft, wordt deze later gebruikt, tenzij u stappen onderneemt om dit te voorkomen.

1
2
3
4
# let op dat de app een FastApi-app is
@app.post ("/ users /", response _ model = User) # hier gebruiken we ormar. Model als reactie
Async def create _ user (gebruiker: gebruiker): # hier gebruiken we ormar. Model in verzoekparameter
    Terug wachten user.save ()

Dit betekent dat als u ie voornaam niet doorgeeft in het verzoek, deze correct zal valideren (aangezien het veld optioneel is) en None zal worden opgeslagen in de database.

Pydantische modellen genereren uit ormar. Model

Omdat het uitsluiten van velden heel gebruikelijk is, heeft Ormar een speciale manier om Pydantische modellen te genereren uit bestaande Ormar. Modellen zonder alle velden opnieuw in te voeren.

Deze methode is de get\ _ pydantic () -methode die beschikbaar is voor alle modelklassen.

1
2
3
4
5
6
# genereer een boom van modellen zonder wachtwoord op gebruikers en zonder prioriteit op geneste categorieën
RequestUser = User. get _ pydantic (exclude = {"wachtwoord":..., "categorie":{"priority"}})
@app.post ("/ users3 /", response _ model = User) # hier kan je ook zowel ormar / pydantic
Async def create _ user3 (gebruiker: RequestUser): # gebruik hier het gegenereerde model
    # let op hoe de gebruiker nu pydantisch is en geen ormar-model, dus u moet converteren
    Retourneren wacht op gebruiker (* * gebruiker. model _ dump ()) .save ()

!!! Opmerking Ga naar het gedeelte get\ _ pydantic van de documentatie om meer voorbeelden te zien en meer te lezen.

WAARSCHUWING De get\ _ pydantic-methode genereert alle modellen in de geneste modelboom op basis van een algoritme waarmee lussen in het model kunnen worden vermeden (hetzelfde algoritme dat wordt gebruikt in model\ _ dump (), select\ _ all (), enz.)

1
2
3
Dat betekent dat geneste modellen geen verwijzingen hebben naar bovenliggende modellen (standaard is de ormarrelatie bidirectioneel).

Merk ook op dat als een bepaald model meer dan eens in een boom voorkomt, het zal worden verdubbeld in pydantische modellen (elk voorval heeft afzonderlijke eigen modellen).

Op die manier kunt u verschillende velden op verschillende bladeren van de boom uitsluiten / opnemen.

MyPy en typecontrole

Houd er rekening mee dat het toewijzen van een functie als een Python-type tijdens runtime overgaat (omdat het niet is aangevinkt), en statische typecontroles zoals MyPy klagen.

Hoewel het resultaat van een functieaanroep altijd hetzelfde is voor een bepaald model, zijn dynamisch gemaakte typen niet toegestaan.

Je hebt dus twee opties:

De eerste is om gewoon # type: negeren toe te voegen om typecontrole over te slaan

1
2
3
4
5
RequestUser = User. get _ pydantic (exclude = {"wachtwoord":..., "categorie":{"priority"}})
@app.post ("/ users3 /", reactie _ model = Gebruiker)
Async def create _ user3 (gebruiker: RequestUser): # type: negeren
    # let op hoe de gebruiker nu geen ormar-model is, dus u moet converteren
    Retourneren wacht op gebruiker (* * gebruiker. model _ dump ()) .save ()

De tweede is wat meer hacky en gebruikt FastAPI om functieparameters te extraheren.

U kunt\ __-annotaties_\ _ -items voor een bepaalde parameter overschrijven.

1
2
3
4
5
6
7
8
RequestUser = User. get _ pydantic (exclude = {"wachtwoord":..., "categorie":{"priority"}})
# gebruik de app-decorateur niet
Async def create _ user3 (gebruiker: gebruiker): # gebruik hier het ormar-model
    Retourneren wacht op gebruiker (* * gebruiker. model _ dump ()) .save ()
# overschrijven van de functie annotaties item voor gebruikersparams met gegenereerde modellen
create _ user3 _ _ annotaties _ _ ["gebruiker"] = RequestUser
# handmatig app-functies aanroepen (app.get, app.post etc.) en uw functiereferentie doorgeven
app.post ("/ categorieën /", response _ model = Gebruiker) (create _ user3)

Merk op dat dit ervoor zorgt dat mypy "denkt" dat de gebruiker een ormar-model is, maar omdat het niet uitmaakt in het verzoek (je zult toch een jsonized dict doorgeven en moeten converteren voordat je opslaat).

Dit zou nog steeds goed moeten werken omdat het resulterende model een subset van de velden zal zijn, dus alle vereiste velden zullen worden gevalideerd en alle ongebruikte velden zullen tijdens runtime mislukken.

Onafhankelijk cantilever model

De uiteindelijke oplossing is om handmatig afzonderlijke Pydantic-modellen te maken. Het werkt precies zoals een normale FastAPI-applicatie, dus je kunt verschillende respons- en aanvraagmodellen gebruiken, enz.

Voorbeeld:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Pydantische invoer

Klasse UserCreate (pydantisch. BaseModel):
    model _ config = pydantic. ConfigDict (van _ attributes = Waar)

    E-mailadres: str
    voornaam: str
    achternaam: str
    Wachtwoord: str


@app.post ("/ users3 /", response _ model = User) # gebruik hier ormar-model (maar je kunt pydantic natuurlijk ook hier gebruiken)
Async def create _ user3 (gebruiker: UserCreate): # gebruik hier een pydantisch model
    # let op hoe nu verzoek param een pydantisch model is en niet de ormar
    # dus je moet het ontleden / converteren naar ormar voordat je database kunt gebruiken
    Retourneren wacht op gebruiker (* * gebruiker. model _ dump ()) .save ()