Problem
Wie im Blogpost Best Practices für das Entwerfen einer pragmatischen RESTful-API empfohlen , möchte ich fields
einer auf Django Rest Framework basierenden API einen Abfrageparameter hinzufügen , mit dem der Benutzer nur eine Teilmenge von Feldern pro Ressource auswählen kann.
Beispiel
Serializer:
class IdentitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Identity
fields = ('id', 'url', 'type', 'data')
Eine reguläre Abfrage würde alle Felder zurückgeben.
GET /identities/
[
{
"id": 1,
"url": "http://localhost:8000/api/identities/1/",
"type": 5,
"data": "John Doe"
},
...
]
Eine Abfrage mit dem fields
Parameter sollte nur eine Teilmenge der Felder zurückgeben:
GET /identities/?fields=id,data
[
{
"id": 1,
"data": "John Doe"
},
...
]
Eine Abfrage mit ungültigen Feldern sollte entweder die ungültigen Felder ignorieren oder einen Clientfehler auslösen.
Tor
Ist das irgendwie sofort möglich? Wenn nicht, wie lässt sich dies am einfachsten umsetzen? Gibt es ein Paket von Drittanbietern, das dies bereits tut?
quelle
QUERY_PARAMS
umquery_params
in den letzten Versionen von Django, aber anders als das dies funktioniert wie ein Charme.requests
es als Mitglied von existiertcontext
. Während der Produktion werden keine Unit-Tests ausgeführt, bei denen die Objekte manuell erstellt werden.Diese Funktionalität ist in einem Paket eines Drittanbieters verfügbar .
Deklarieren Sie Ihren Serializer wie folgt:
Dann können die Felder jetzt (clientseitig) mithilfe von Abfrageargumenten angegeben werden:
Eine Ausschlussfilterung ist ebenfalls möglich, z. B. um jedes Feld außer id zurückzugeben:
Haftungsausschluss: Ich bin der Autor / Betreuer.
quelle
dbrgn
Implementierung weist jedoch einige Unterschiede auf: 1. unterstützt nicht das Ausschließen mitfields!=key1,key2
. 2. Ändert auch Serialisierer außerhalb des GET-Anforderungskontexts, wodurch einige PUT / POST-Anforderungen unterbrochen werden können und werden. 3. sammelt keine Felder mit zBfields=key1&fields=key2
, was für Ajax-Apps eine gute Sache ist. Es hat auch keine Testabdeckung, was in OSS etwas ungewöhnlich ist.serializers.py
views.py
quelle
Konfigurieren Sie eine neue Paginierungs-Serializer-Klasse
Dynamischen Serializer erstellen
Verwenden Sie zuletzt ein Homemage-Mixin für Ihre APIViews
Anfrage
Wenn Sie jetzt eine Ressource anfordern, können Sie einen Parameter hinzufügen
fields
, um nur bestimmte Felder in der URL anzuzeigen./?fields=field1,field2
Eine Erinnerung finden Sie hier: https://gist.github.com/Kmaschta/e28cf21fb3f0b90c597a
quelle
Sie können Dynamic REST ausprobieren , das dynamische Felder (Einschluss, Ausschluss), eingebettete / seitlich geladene Objekte, Filterung, Reihenfolge, Paginierung und mehr unterstützt.
quelle
Diese Funktionalität haben wir in den Feldern drf_tweaks / control-over-serialized-fields bereitgestellt .
Wenn Sie unsere Serializer verwenden, müssen Sie lediglich
?fields=x,y,z
Parameter in der Abfrage übergeben.quelle
Bei verschachtelten Daten, ich bin mit Django Ruhe Framework mit dem Paket in dem empfohlenen docs , DRF-flexfields
Auf diese Weise können Sie die Felder einschränken, die sowohl für das übergeordnete als auch für das untergeordnete Objekt zurückgegeben werden. Die Anweisungen in der Readme-Datei sind gut, nur ein paar Dinge, auf die Sie achten sollten:
Die URL scheint das / wie folgt zu benötigen: '/ person /? Expand = country & fields = id, name, country' anstatt wie in der Readme geschrieben '/ person? Expand = country & fields = id, name, country'.
Die Benennung des verschachtelten Objekts und des zugehörigen Namens muss vollständig konsistent sein, was sonst nicht erforderlich ist.
Wenn Sie "viele" haben, z. B. kann ein Land viele Bundesstaaten haben, müssen Sie "viele" festlegen: True im Serializer, wie in den Dokumenten beschrieben.
quelle
Wenn Sie etwas Flexibles wie GraphQL wollen, können Sie django-restql verwenden . Es unterstützt verschachtelte Daten (sowohl flach als auch iterierbar).
Beispiel
Eine reguläre Anfrage gibt alle Felder zurück.
GET /users
Eine Anfrage mit dem
query
Parameter gibt dagegen nur eine Teilmenge der Felder zurück:GET /users/?query={id, username}
Mit django-restql können Sie auf verschachtelte Felder jeder Ebene zugreifen. Z.B
GET /users/?query={id, username, date_joined{year}}
Bei iterierbaren verschachtelten Feldern z. B. Gruppen für Benutzer.
GET /users/?query={id, username, groups{id, name}}
quelle