Django-rest-framework: Wie lege ich einen Feldtyp in SerializerMethodField für die OpenAPI-Schemagenerierung fest?

Erstellt am 13. Jan. 2020  ·  3Kommentare  ·  Quelle: encode/django-rest-framework

Betrachten Sie diesen nutzlosen Serializer:

class MySerializer(serializers.Serializer):

    random_number = serializers.SerializerMethodField()

    def get_random_number(self):
        # Chosen by fair dice roll.
        # Guaranteed to be random.
        return 4

Angenommen, Sie haben diesen Serializer in einem Endpunkt hinzugefügt und das OpenAPI-Schema generiert, dann würde der Serializer so aussehen:

properties:
  random_number:
    type: string
  required:
  - random_number

Das Problem hier ist, dass es keine Möglichkeit gibt, DRF anzuweisen, hier type: number . Ich habe mir ein paar Möglichkeiten überlegt:

  • Ein output_field Attribut, wie serializers.SerializerMethodField(output_field=serializers.IntegerField()) , ähnlich wie Djangos Abfrageausdrücke
  • Ein Dekorateur, wie openapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
  • Ein Attribut, ähnlich wie bei Einstellungsbeschreibungen für Administratoraktionen :

    random_number = serializers.SerializerMethodField()
    
    def get_random_number(self):
      return 4
    
    get_random_number.output_field = serializers.IntegerField()
    
  • Einfach etwas, das DRF nicht unterstützt, was wahrscheinlich irgendwo als möglicher Vorbehalt dokumentiert werden sollte.
Enhancement Schema Generation

Hilfreichster Kommentar

Für mich ist die API, die ich bevorzugen würde, etwas, das Typhinweise verwendet wie:

def get_foo(self, obj) -> int:
    return 1

Es funktioniert in jeder derzeit unterstützten Python-Version. Diese Idee wurde in https://github.com/encode/django-rest-framework/pull/7089 verwendet, aber nicht in einen anderen PR unterteilt. Wenn man sich diese Implementierung ansieht, scheint es, als würde sie keine Sammlungen verarbeiten. Irgendwann wäre es besser, einen verschachtelten Serializer zu verwenden, aber ich denke, einfache Fälle wie List[int] , List[str] , Dict[str, int] usw. sollten unterstützt werden.

@carlfarrington was denkst du? Lohnt es sich diesen Ansatz auszuprobieren oder gibt es Probleme damit? Wenn es einen Versuch wert ist, lohnt es sich auch, etwas grundlegendes zu bekommen, das mit grundlegenden Typen umgehen und verschachtelte Felder vorerst ignorieren kann, oder würden wir (verschachtelte oder nicht) Arrays und Objekte von Anfang an wollen?

Alle 3 Kommentare

Hallo @Lucidiot.

Ich denke, der unmittelbare Weg, dies zu tun, wäre, AutoSchema._map_field() zu überschreiben.

Sie können dies entweder pro Serializer/Ansicht tun, um das fragliche Feld zu erwarten, oder ein Attribut hinzufügen, wie Sie es sagen.

Wir werden irgendwann auf diese Weise zu etwas kommen, aber derzeit bin ich mir nicht sicher, was die beste Option in Bezug auf die API ist.

Für mich ist die API, die ich bevorzugen würde, etwas, das Typhinweise verwendet wie:

def get_foo(self, obj) -> int:
    return 1

Es funktioniert in jeder derzeit unterstützten Python-Version. Diese Idee wurde in https://github.com/encode/django-rest-framework/pull/7089 verwendet, aber nicht in einen anderen PR unterteilt. Wenn man sich diese Implementierung ansieht, scheint es, als würde sie keine Sammlungen verarbeiten. Irgendwann wäre es besser, einen verschachtelten Serializer zu verwenden, aber ich denke, einfache Fälle wie List[int] , List[str] , Dict[str, int] usw. sollten unterstützt werden.

@carlfarrington was denkst du? Lohnt es sich diesen Ansatz auszuprobieren oder gibt es Probleme damit? Wenn es einen Versuch wert ist, lohnt es sich auch, etwas grundlegendes zu bekommen, das mit grundlegenden Typen umgehen und verschachtelte Felder vorerst ignorieren kann, oder würden wir (verschachtelte oder nicht) Arrays und Objekte von Anfang an wollen?

Wir bewerben und dokumentieren map_field() für 3.12. Das ist hier der richtige Weg.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen