Ga naar inhoud

antwoord

U kunt het ormatiemodel gebruiken in plaats van het pydantische model in het fastapi response\ _ model.

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

Een van de meest voorkomende taken in een reactie is het uitsluiten van bepaalde velden die u niet in de antwoordgegevens wilt opnemen.

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 de reactie

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:

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 valideert (omdat het veld optioneel is), opslaat in de database en een opgeslagen record retourneert zonder dit veld (dat ook valideert).

!!!Merk op dat hoewel u de veldwaarde niet hebt doorgegeven, het veld zelf nog steeds bestaat in response\ _ model, wat betekent dat het in de responsgegevens zal verschijnen en op Geen zal worden ingesteld.

1
Als u het veld volledig wilt uitsluiten van het resultaat, lees dan verder.

FastApi-reactie_-model_-uitsluiting

FastAPI heeft een reactie\ _ model\ _ exclude die een set (of lijst) met veldnamen accepteert.

Dit heeft zijn beperkingen omdat Ormar en Pydantic ook woordenboeken accepteren waarin u uitsluitings- / inclusiekolommen of geneste modellen kunt instellen (meer hierover hieronder).

Waarschuwing Merk op dat een vereist veld niet kan worden uitgesloten bij gebruik van response\ _ model, omdat het tijdens validatie mislukt.

1
2
3
@app.post ("/ users /", response _ model = Gebruiker, response _ model _ exclude ={"password"})
Async def create _ user (gebruiker: Gebruiker):
    Terug wachten user.save ()

Het bovenstaande eindpunt kan als volgt worden opgevraagd:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Vanaf starlette.testclient importeren TestClient

Opdrachtgever = TestClient (app)

Met cliënten als cliënten:
        # nootje er staat geen pk
        Gebruiker = {
            "E-mail": "test@domain.com",
            "Wachtwoord": "^*^% A*DA * IAAA",
            "voornaam": "John",
            "achternaam": "Doe",
        }
        Reactie = client.post ("/ users /", json = user)
        # merk op dat het uitgesloten veld volledig is verdwenen uit reactie
        Bevestig "wachtwoord" niet in response.json ()
        # lees de reactie en initialiseer het model uit het
        aangemaakt _ gebruiker = Gebruiker (* * response.json ())
        # note pk wordt bevolkt door autoincrement
        Beweren created_user.pk is geen Geen
        # Merk op dat het wachtwoord ook ontbreekt in het geïnitialiseerde model
        Beweren gemaakt _ gebruikerswachtwoord is Geen

Merk op hoe het wachtwoordveld volledig verdwijnt uit de antwoordgegevens in het bovenstaande voorbeeld.

1
Merk op dat u deze methode alleen kunt gebruiken voor niet-verplichte velden.

Uitsluiting genest model

Hoewel fastapi alleen het doorgeven van een set veldnamen toestaat, dus het is gewoon uitgesloten, is ormar slimmer bij het gebruik van response\ _ model\ _ exclude.

In Ormar kunt u twee soorten notaties gebruiken om geneste modellen uit te sluiten.

De eerste is een woordenboek met geneste velden die de modelboomstructuur vertegenwoordigen, en de tweede is een dubbel onderstreept pad naar de veldnamen.

Stel dat onze gebruikerscategorie een apart model is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
basis _ ormar _ config = ormar. OrmarConfig (
    Metagegevens = metagegevens
    Database = database
)

Klasse Categorie (ormar. Model):
    ormar _ config = basis _ ormar _ config (tabelnaam = "categorieën")

    Id: int = ormar. Geheel getal (primaire _ sleutel = waar)
    Naam: str = ormar. String (max _ length = 255)
    Prioriteit: int = ormar. Geheel getal (nullable = Waar)


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: Optioneel [Categorie] = ormar. ForeignKey (Categorie, gerelateerde _ naam = "categorieën")

Als u prioriteit van categorieën in een reactie wilt uitsluiten, kunt u nog steeds de fastAPI-parameter gebruiken.

1
2
3
@app.post ("/ users /", response _ model = Gebruiker, response _ model _ exclude ={"category__priority"})
Async def create _ user (gebruiker: Gebruiker):
    Terug wachten user.save ()

Merk op dat u dubbele onderstrepingstekens kunt gebruiken om dieper in het model te gaan, en als u meerdere velden van het geneste model wilt uitsluiten, moet u ze voorafgaan met het volledige pad. In het voorbeeld response_model_exclude={"category__priority", "category__other_field", category__nested_model__nested_model_field} ETC.

!!!Opmerking Ga naar de sectie Velden van de documentatie voor meer informatie over mogelijke uitsluitingen en het bouwen van een uitsluitingswoordenboek of instellingen.

Merk op dat naast de responsparameters\ _ model\ _ exclude, fastapi ook andere parameters ondersteunt die zijn overgenomen van pydantic. Dit alles werkt ook met ormar, maar er kunnen enkele nuances zijn, dus het is het beste om het dict-gedeelte van de documentatie te lezen.

Uitsluiten in Model.model\ _ dump ()

Of u kunt gewoon een woordenboek van ormar retourneren. Modelleer en gebruik het.

Op deze manier kunt u ook Uitsluiten / Opnemen als woordenboek instellen en velden op geneste modellen uitsluiten.

!!!Waarschuwing Als u geen respons\ _ model gebruikt, heeft de API-documentatie geen responsvoorbeelden en schema 's, omdat de respons in theorie elk formaat kan hebben.

1
2
3
4
5
@app.post ("/ users2 /", reactie _ model = Gebruiker)
Async def create _ user2 (gebruiker: Gebruiker):
    Gebruiker = user.save ()
    Retourneer gebruikersmodel _ dump (uitsluiten ={'password'})
    # kan ook zoiets zijn als retourgebruiker. model _ dump (exclude = {'category':{'priority'}}) om categorieprioriteit uit te sluiten

!!!Merk op dat zelfs als u het wachtwoordveld in het verzoek doorgeeft, het bovenstaande voorbeeld het wachtwoordveld ongeldig maakt, maar het veld blijft bestaan omdat het deel uitmaakt van het antwoordschema en de waarde wordt ingesteld op Geen.

Als je het veld op deze manier volledig wilt uitsluiten, gebruik dan gewoon geen response\ _ model en sluit het uit in het model\ _ dump ()

Of u kunt gewoon een woordenboek van een ormar-model retourneren. Op deze manier kunt u ook Uitsluiten / Opnemen instellen in een woordenboek en velden op geneste modellen uitsluiten.

!!!Merk op dat u in theorie de responsvalidatie hier verliest, maar omdat u op ormar werkt. Modellen, worden de responsgegevens al gevalideerd na de databasequery (omdat het ormar-model een pydantisch model is).

Dus als je reactie\ _ model helemaal overslaat kun je het volgende doen:

1
2
3
4
@app.post ("/ users4 /") # nootje geen reactie _ model
Async def create _ user4 (gebruiker: Gebruiker):
    Gebruiker = user.save ()
    Retourneer gebruikersmodel _ dump (uitsluiten ={'last_name'})

!!!Merk op dat wanneer u antwoord\ _ model overslaat, u nu ook vereiste velden kunt uitsluiten omdat het antwoord niet langer wordt gevalideerd na het retourneren.

1
De kosten van deze oplossing zijn dat u ook api-documentatie verliest als responsschema in onbekend vanuit fastapi-perspectief.

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
# genereer een boom van modellen zonder wachtwoord op gebruikers en zonder prioriteit op geneste categorieën
ResponseUser = Gebruiker. get _ pydantic (exclude = {"wachtwoord":..., "categorie":{"priority"}})
@app.post ("/ users3 /", response _ model = ResponseUser) # gebruik hier het gegenereerde model
Async def create _ user3 (gebruiker: Gebruiker):
    Terug wachten user.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.

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
Pydantische invoer

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

    E-mailadres: str
    voornaam: str
    achternaam: str


@app.post ("/ users3 /", response _ model = UserBase) # gebruik hier een pydantisch model
Async def create _ user3 (gebruiker: Gebruiker): # gebruik hier het ormar-model (maar je kunt pydantic natuurlijk ook hier gebruiken)
    Terug wachten user.save ()