Django-rest-framework: Comment définir un type de champ sur SerializerMethodField pour la génération de schéma OpenAPI ?

Créé le 13 janv. 2020  ·  3Commentaires  ·  Source: encode/django-rest-framework

Considérez ce sérialiseur inutile :

class MySerializer(serializers.Serializer):

    random_number = serializers.SerializerMethodField()

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

En supposant que vous ayez ajouté ce sérialiseur dans un point de terminaison et généré le schéma OpenAPI, le sérialiseur ressemblerait à ceci :

properties:
  random_number:
    type: string
  required:
  - random_number

Le problème ici est qu'il n'y a aucun moyen de dire à DRF d'utiliser type: number ici. J'ai pensé à quelques possibilités :

  • Un attribut output_field , comme serializers.SerializerMethodField(output_field=serializers.IntegerField()) , similaire aux expressions de requête de Django
  • Un décorateur, comme openapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
  • Un attribut, similaire à la définition des descriptions sur les actions d'administration :

    random_number = serializers.SerializerMethodField()
    
    def get_random_number(self):
      return 4
    
    get_random_number.output_field = serializers.IntegerField()
    
  • Simplement quelque chose que DRF ne prend pas en charge, ce qui devrait probablement être documenté quelque part comme une mise en garde possible.
Enhancement Schema Generation

Commentaire le plus utile

Pour moi, je pense que l'API que je préfère est quelque chose qui utilise des indices de type comme :

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

Il fonctionne dans toutes les versions de Python actuellement prises en charge. Cette idée a été utilisée dans https://github.com/encode/django-rest-framework/pull/7089 mais elle n'a pas été séparée dans un autre PR. En regardant cette implémentation, il semble qu'elle ne gère pas les collections. À un moment donné, vous feriez mieux d'utiliser un sérialiseur imbriqué, mais je pense que des cas simples comme List[int] , List[str] , Dict[str, int] etc. devraient être pris en charge.

@carlfarrington qu'en pensez-vous ? Cela vaut-il la peine d'essayer cette approche ou cela pose-t-il des problèmes ? Si cela vaut la peine d'essayer, cela vaut-il également la peine d'obtenir quelque chose de basique capable de gérer les types de base et d'ignorer les champs imbriqués pour le moment ou voudrions-nous des tableaux et des objets (imbriqués ou non) dès le début ?

Tous les 3 commentaires

Salut @Lucidiot.

Je suppose que la façon immédiate de le faire serait de remplacer AutoSchema._map_field() .

Vous pouvez soit faire ce sérialiseur/vue pour attendre le champ en question, soit ajouter un attribut comme vous le dites.

Nous finirons par arriver à quelque chose de cette manière, mais actuellement, je ne suis pas sûr de la meilleure option, en termes d'API.

Pour moi, je pense que l'API que je préfère est quelque chose qui utilise des indices de type comme :

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

Il fonctionne dans toutes les versions de Python actuellement prises en charge. Cette idée a été utilisée dans https://github.com/encode/django-rest-framework/pull/7089 mais elle n'a pas été séparée dans un autre PR. En regardant cette implémentation, il semble qu'elle ne gère pas les collections. À un moment donné, vous feriez mieux d'utiliser un sérialiseur imbriqué, mais je pense que des cas simples comme List[int] , List[str] , Dict[str, int] etc. devraient être pris en charge.

@carlfarrington qu'en pensez-vous ? Cela vaut-il la peine d'essayer cette approche ou cela pose-t-il des problèmes ? Si cela vaut la peine d'essayer, cela vaut-il également la peine d'obtenir quelque chose de basique capable de gérer les types de base et d'ignorer les champs imbriqués pour le moment ou voudrions-nous des tableaux et des objets (imbriqués ou non) dès le début ?

Nous allons promouvoir et documenter map_field() pour 3.12. C'est la bonne façon d'aller ici.

Cette page vous a été utile?
0 / 5 - 0 notes