Zum Inhalt

Forderung

Sie können das ormar-Modell anstelle des pydantischen Modells in fastapi-Anforderungen für das Hauptargument verwenden.

Natürlich können Sie ormar. Models auch mit pydantic kombinieren, wenn Sie wollen.

Eine der häufigsten Aufgaben in Anforderungen besteht darin, bestimmte Felder auszuschließen, die Sie nicht in die an die API gesendete Last einbeziehen möchten.

Es gibt mehrere Möglichkeiten, dies in ormar zu erreichen, so dass Sie unten Ihre Optionen überprüfen und die auswählen können, die Ihrer Situation am besten entspricht.

Ausschließen der im Antrag angegebenen Wörter

Auswählen des Wortes

Beachten Sie, dass keines der optionalen Felder erforderlich ist, was bedeutet, dass Sie sowohl in Antworten als auch in Anforderungen überspringen können.

Felder werden nicht benötigt, wenn (ein/viele/alle) der folgende Fall vorliegt:

  • Felder mit dem Tag nullable = true
  • Das Feld hat den Standardwert oder bietet eine Funktion namens default ="Test".
  • Das Feld legt den Wert server_default fest. Das* -Feld ist ein Feld mit autoincrement = Trueprimary_key (beachten Sie, dass ormar. Integercrimary_key standardmäßig autoincrement ist).

Beispiel:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Die Abbildung zeigt die Konfidenzintervalle für die Konfidenzintervalle: (
    Metathek = Metathek
    Datengrundlage = Datenbank
)

Klasse Benutzer (ormar. Model):
    ormar_config = base_ormar_config. copy ()(= Grundeinheit von ormar_config. copy)

    id: int = ormar. Integer (primary_key = true)(nicht bekannt)
    E-Mail: str = ormar. String (max_length = 255)
    Passwort: str = ormar. String (max_length = 255)
    first_name: str = ormar. String (max_length = 255, nullable = true)(string = ormar. String (max_length = 255, nullable = true) ist ein
    last_name: str = ormar. String (max_length = 255) string = ormar. string (max_length = 255) ist ein
    Kategorie: str = ormar. String (max_length = 255, default ="Benutzer")

Im obigen Beispiel sind die Felder id (eine automatisch inkrementelle Ganzzahl) , first \ _ name (mit nullable = True) und class (mit dem Standardwert) optional , können in der Antwort übersprungen werden und das Modell wird weiterhin validiert .

Wenn das Feld leer sein kann , muss es nicht während der Erstellung und in der Antwort in die Nutzlast einbezogen werden , sodass Sie anhand des obigen Beispiels Folgendes tun können :

Warnung Beachten Sie , dass Sie zwar kein optionales Feld übergeben müssen , dies jedoch tun können , wenn jemand einen Wert übergibt , wird er später verwendet , es sei denn , Sie ergreifen Maßnahmen , um ihn zu verhindern .

1
2
3
4
Diese App ist eine FastApi App
@app.post("/users/" , response _ model = User) # hier verwenden wir ormar .
async def create _ user (Benutzer : Benutzer) : # Hier verwenden wir ormar . Model in request parameter
    return await Zurückuser.save()

Dies bedeutet , dass , wenn Sie in der Anforderung nicht den ie first \ _ name übergeben , er korrekt überprüft wird (da das Feld optional ist) und None in der Datenbank gespeichert wird .

Erzeugen eines pydantischen Modells aus einem ormar . Model

Da das Ausschließen von Feldern üblich ist , bietet ormar eine spezielle Möglichkeit , pydantische Modelle aus vorhandenen ormar . Models zu generieren , ohne alle Felder erneut eingeben zu müssen .

Die Methode ist die get _ pydantic () - Methode , die in allen Modellklassen verfügbar ist .

1
2
3
4
5
6
Erstellen Sie einen Baum von Modellen ohne Passwort für den Benutzer und ohne Priorität für die angegebene Kategorie .
RequestUser = User. get_pydantic (exclude ={"Passwort":...,"Kategorie": {"priority"}})
@app.post("/users3/" , response _ model = User) # Hier können Sie auch beide Ormar/Pydantische Elemente verwenden
async def create_user3 (user : RequestUser) : # use the generated model here [ Bearbeiten | Quelltext bearbeiten ]
    Wie Benutzer jetzt pydantisch sind und kein ormares Modell , so dass Sie konvertieren müssen
    return await Benutzer (* * user . model _ dump ()) . save ()

Um mehr Beispiele zu sehen und mehr zu lesen , besuchen Sie bitte den Abschnitt get _ pydantic der Dokumentation .

Die get _ pydantic-Methode generiert alle Modelle in einem verschachtelten Modellbaum basierend auf Algorithmen , die es ermöglichen , Schleifen in einem Modell zu vermeiden (dieselben Algorithmen , die in model _ dump () , select \ _ all () usw . verwendet werden) .

1
2
3
Das bedeutet , dass nicht verwandte Modelle keine Referenz zu parent-Modellen haben werden (durch die voreingestellte Ormar-Beziehung ist bidirektiv) .

Auch wenn das Modell mehr in einem Baum existiert , als einmal , wird es in pydantischen Modellen verdoppelt (jede Abweichung wird ein eigenes Modell haben) .

MyPy und Typenprüfung

Beachten Sie , dass das Zuweisen einer Funktion zum Python-Typ zur Laufzeit (weil es nicht geprüft wird) übergeben wird , und statische Typprücker wie mypy werden sich beschweren .

Obwohl das Ergebnis eines Funktionsaufrufs für ein bestimmtes Modell immer gleich ist , sind dynamisch erstellte Typen nicht zulässig .

Sie haben also zwei Optionen :

type : ignore hinzufügen , um die Typüberprüfung zu umgehen

1
2
3
4
5
RequestUser = User . get _ pydantic (exclude = {" password " : ... , " category " :{"priority"}})
@app.post("/users3/" ; response _ model = Benutzer)
async def create_user3 (Benutzer : RequestUser) : # type : ignore
    # Hinweis : Benutzer sind jetzt keine Ormar-Modelle , so dass Sie konvertieren müssen
    return await Benutzer (* * user . model _ dump ()) . save ()

Die zweite ist ein bisschen hacky , die Art und Weise fastapi verwendet , um Funktionsparameter zu extrahieren .

Sie können den Eintrag \ _ _annotations _\ _ für einen bestimmten Parameter überschreiben .

1
2
3
4
5
6
7
8
RequestUser = User . get _ pydantic (exclude = {" password " : ... , " category " :{"priority"}})
Verwenden Sie nicht den App-Dekorator
async def create_user3 (Benutzer : Benutzer) : # use ormar model here
    return await Benutzer (* * user . model _ dump ()) . save ()
# overwrite the function annotations entry for user param with generated model (Funktionsannotationen für Benutzerparam mit generiertem Modell)
create_user3._annotations _ _ [ " Benutzer " ] = RequestUser
Manually call app functions (manuell aufrufen)app.postetc.) und geben Sie Ihre Funktionsreferenz ein
app.post("/categories/" , response _ model = User) (create_user3) ("/categories/" , response _ model = Benutzer)

Beachten Sie , dass dies dazu führt , dass mypy " denkt " , dass der Benutzer ein ormar-Modell ist , aber da es in der Anfrage nicht wichtig ist (Sie übergeben sowieso ein jsonized dict und müssen konvertieren , bevor Sie speichern) .

Dies sollte immer noch funktionieren , da das generierte Modell eine Teilmenge der Felder sein wird , daher werden alle erforderlichen Felder überprüft , und alle nicht verwendeten Felder werden zur Laufzeit fehlschlagen .

Eigenständiges Ausleger-Modell

Die endgültige Lösung besteht darin , separate Pydantic-Modelle manuell zu erstellen , die genau wie normale Fastapi-Anwendungen funktionieren , sodass Sie unter anderem unterschiedliche Antworten und Anfragemodelle verwenden können .

Sample sein :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Import von Pydantika

UserCreate class (pydantic . BaseModel) :
    model _ config = pydantic . ConfigDict (von _ attributes = True)

    E-Mail schreiben : str
    Vorname : str
    Vorname : str
    Password : str


@app.post("/users3/" , response _ model = User) # use ormar model here (aber natürlich können Sie auch hier verwenden)
async def create_user3 (Benutzer : UserCreate) : # use pydantisches Modell hier
    Der jetzt angeforderte Parameter ist ein pydantisches Modell und nicht der Ormar .
    Also müssen Sie parken/konvertieren Sie es , bevor Sie die Datenbank verwenden können
    return await Benutzer (* * user . model _ dump ()) . save ()