Django-rest-framework: Bagaimana cara mengatur jenis bidang pada SerializerMethodField untuk pembuatan skema OpenAPI?

Dibuat pada 13 Jan 2020  ·  3Komentar  ·  Sumber: encode/django-rest-framework

Pertimbangkan serializer yang tidak berguna ini:

class MySerializer(serializers.Serializer):

    random_number = serializers.SerializerMethodField()

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

Dengan asumsi Anda menambahkan serializer ini di titik akhir dan menghasilkan skema OpenAPI, serializer akan terlihat seperti ini:

properties:
  random_number:
    type: string
  required:
  - random_number

Masalahnya di sini adalah tidak ada cara untuk memberi tahu DRF untuk menggunakan type: number sini. Saya memikirkan beberapa kemungkinan:

  • Atribut output_field , seperti serializers.SerializerMethodField(output_field=serializers.IntegerField()) , mirip dengan Ekspresi Kueri Django
  • Seorang dekorator, seperti openapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
  • Atribut, mirip dengan deskripsi pengaturan pada tindakan admin :

    random_number = serializers.SerializerMethodField()
    
    def get_random_number(self):
      return 4
    
    get_random_number.output_field = serializers.IntegerField()
    
  • Hanya sesuatu yang tidak didukung DRF, yang mungkin harus didokumentasikan di suatu tempat sebagai kemungkinan peringatan.
Enhancement Schema Generation

Komentar yang paling membantu

Bagi saya, saya pikir API yang saya sukai adalah sesuatu yang menggunakan petunjuk tipe seperti:

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

Ini berfungsi di setiap versi Python yang saat ini didukung. Ide ini digunakan di https://github.com/encode/Django-rest-framework/pull/7089 tetapi tidak dipisahkan menjadi PR lain. Melihat implementasi itu, sepertinya tidak menangani koleksi. Pada titik tertentu Anda akan lebih baik menggunakan serializer bersarang, tetapi saya pikir kasus sederhana seperti List[int] , List[str] , Dict[str, int] dll. harus didukung.

@carlfarrington bagaimana menurutmu? Apakah layak mencoba pendekatan ini atau ada masalah dengannya? Jika layak untuk dicoba, apakah layak juga mendapatkan sesuatu yang mendasar yang dapat menangani tipe dasar dan mengabaikan bidang bersarang untuk saat ini atau apakah kita ingin (bersarang atau tidak) array dan objek dari awal?

Semua 3 komentar

Hai @Lucidiot.

Saya kira cara langsung untuk melakukan ini adalah dengan menimpa AutoSchema._map_field() .

Anda dapat melakukan per-serializer/tampilan untuk mengharapkan bidang yang dimaksud, atau menambahkan atribut seperti yang Anda katakan.

Kami akan menemukan sesuatu dengan cara ini pada akhirnya, tetapi saat ini saya tidak yakin tentang opsi terbaik, dalam hal API.

Bagi saya, saya pikir API yang saya sukai adalah sesuatu yang menggunakan petunjuk tipe seperti:

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

Ini berfungsi di setiap versi Python yang saat ini didukung. Ide ini digunakan di https://github.com/encode/Django-rest-framework/pull/7089 tetapi tidak dipisahkan menjadi PR lain. Melihat implementasi itu, sepertinya tidak menangani koleksi. Pada titik tertentu Anda akan lebih baik menggunakan serializer bersarang, tetapi saya pikir kasus sederhana seperti List[int] , List[str] , Dict[str, int] dll. harus didukung.

@carlfarrington bagaimana menurutmu? Apakah layak mencoba pendekatan ini atau ada masalah dengannya? Jika layak untuk dicoba, apakah layak juga mendapatkan sesuatu yang mendasar yang dapat menangani tipe dasar dan mengabaikan bidang bersarang untuk saat ini atau apakah kita ingin (bersarang atau tidak) array dan objek dari awal?

Kami akan mempromosikan dan mendokumentasikan map_field() untuk 3.12. Itu cara yang tepat untuk pergi ke sini.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat