Masalah
Seperti yang direkomendasikan dalam Best Practices for Designing a Pragmatic RESTful API , saya ingin menambahkan fields
parameter kueri ke API berbasis Django Rest Framework yang memungkinkan pengguna untuk memilih hanya subset bidang per sumber daya.
Contoh
Serializer:
class IdentitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Identity
fields = ('id', 'url', 'type', 'data')
Kueri biasa akan mengembalikan semua bidang.
GET /identities/
[
{
"id": 1,
"url": "http://localhost:8000/api/identities/1/",
"type": 5,
"data": "John Doe"
},
...
]
Kueri dengan fields
parameter seharusnya hanya mengembalikan subset bidang:
GET /identities/?fields=id,data
[
{
"id": 1,
"data": "John Doe"
},
...
]
Kueri dengan bidang tidak valid harus mengabaikan bidang yang tidak valid atau menimbulkan kesalahan klien.
Tujuan
Apakah ini mungkin di luar kotak entah bagaimana? Jika tidak, apa cara termudah untuk menerapkan ini? Apakah ada paket pihak ke-3 yang sudah melakukan ini?
sumber
QUERY_PARAMS
kequery_params
dalam versi terbaru Django, tapi selain itu ini bekerja seperti pesona.requests
ada sebagai anggotacontext
. Meskipun dalam produksi, ia tidak menjalankan pengujian unit yang membuat objek secara manual.Fungsionalitas ini tersedia dari paket pihak ketiga .
Deklarasikan pembuat serial Anda seperti ini:
Kemudian bidang sekarang dapat ditentukan (sisi klien) dengan menggunakan argumen kueri:
Pemfilteran pengecualian juga dimungkinkan, misalnya mengembalikan setiap bidang kecuali id:
disclaimer: Saya adalah penulis / pengelola.
sumber
dbrgn
implementasinya memiliki beberapa perbedaan: 1. tidak mendukung exclude withfields!=key1,key2
. 2. juga memodifikasi serializers di luar konteks permintaan GET, yang dapat dan akan merusak beberapa permintaan PUT / POST. 3. tidak mengakumulasi bidang misalnyafields=key1&fields=key2
, yang bagus untuk dimiliki untuk aplikasi ajax. Ini juga memiliki cakupan tes nol, yang agak tidak biasa di OSS.serializers.py
views.py
sumber
Konfigurasikan kelas serializer pagination baru
Buat serializer dinamis
Terakhir, gunakan campuran homemage untuk APIViews Anda
Permintaan
Sekarang, saat Anda meminta sumber daya, Anda dapat menambahkan parameter
fields
untuk hanya menampilkan bidang tertentu di url./?fields=field1,field2
Anda dapat menemukan pengingat di sini: https://gist.github.com/Kmaschta/e28cf21fb3f0b90c597a
sumber
Anda dapat mencoba Dynamic REST , yang memiliki dukungan untuk bidang dinamis (penyertaan, pengecualian), objek yang disematkan / dipindahkan, pemfilteran, pengurutan, penomoran halaman, dan banyak lagi.
sumber
Fungsionalitas yang kami sediakan di drf_tweaks / control-over-serialized-fields .
Jika Anda menggunakan serializers kami, yang Anda butuhkan hanyalah meneruskan
?fields=x,y,z
parameter dalam kueri.sumber
Untuk data bersarang, saya menggunakan Django Rest Framework dengan paket yang direkomendasikan di dokumen , drf-flexfields
Ini memungkinkan Anda untuk membatasi bidang yang dikembalikan pada objek induk dan anak. Instruksi di readme bagus, hanya beberapa hal yang harus diperhatikan:
URL tampaknya membutuhkan / seperti ini '/ person /? Expand = country & field = id, name, country' alih-alih seperti yang tertulis di readme '/ person? Expand = country & fields = id, name, country'
Penamaan objek bertingkat dan nama terkaitnya harus benar-benar konsisten, yang tidak diperlukan sebaliknya.
Jika Anda memiliki 'many' misalnya suatu negara dapat memiliki banyak negara bagian, Anda harus menyetel 'many': True di Serializer seperti yang dijelaskan di dokumen.
sumber
Jika Anda menginginkan sesuatu yang fleksibel seperti GraphQL, Anda dapat menggunakan django-restql . Ini mendukung data bersarang (flat dan iterable).
Contoh
Permintaan reguler mengembalikan semua bidang.
GET /users
Permintaan dengan
query
parameter di sisi lain hanya mengembalikan subset bidang:GET /users/?query={id, username}
Dengan django-restql Anda bisa mengakses bidang bersarang di tingkat manapun. Misalnya
GET /users/?query={id, username, date_joined{year}}
Untuk bidang bersarang yang dapat diulang, misalnya grup pada pengguna.
GET /users/?query={id, username, groups{id, name}}
sumber