Problem
Zgodnie z zaleceniami zamieszczonymi w blogu Best Practices for Designing a Pragmatic RESTful API , chciałbym dodać fields
parametr zapytania do interfejsu API opartego na Django Rest Framework, który pozwala użytkownikowi wybrać tylko podzbiór pól na zasób.
Przykład
Serializator:
class IdentitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Identity
fields = ('id', 'url', 'type', 'data')
Zwykłe zapytanie zwróciłoby wszystkie pola.
GET /identities/
[
{
"id": 1,
"url": "http://localhost:8000/api/identities/1/",
"type": 5,
"data": "John Doe"
},
...
]
Zapytanie z fields
parametrem powinno zwracać tylko podzbiór pól:
GET /identities/?fields=id,data
[
{
"id": 1,
"data": "John Doe"
},
...
]
Zapytanie z nieprawidłowymi polami powinno albo zignorować nieprawidłowe pola, albo zgłosić błąd klienta.
Cel
Czy jest to jakoś możliwe po wyjęciu z pudełka? Jeśli nie, jaki jest najprostszy sposób na wdrożenie tego? Czy istnieje pakiet innej firmy, który już to robi?
źródło
QUERY_PARAMS
naquery_params
w ostatnich wersjach Django, ale poza tym działa to jak urok.requests
istnieje jako członekcontext
. Chociaż działa to w środowisku produkcyjnym, nie dzieje się tak podczas uruchamiania testów jednostkowych, które ręcznie tworzą obiekty.Ta funkcja jest dostępna w pakiecie innej firmy .
Zadeklaruj swój serializator w ten sposób:
Następnie pola można teraz określić (po stronie klienta) za pomocą argumentów zapytania:
Możliwe jest również filtrowanie wykluczeń, np. Aby zwrócić każde pole oprócz id:
zastrzeżenie: jestem autorem / opiekunem.
źródło
dbrgn
implementacja ma pewne różnice: 1. nie obsługuje wykluczania zfields!=key1,key2
. 2. modyfikuje również serializatory poza kontekstem żądania GET, co może i będzie przerywać niektóre żądania PUT / POST. 3. nie gromadzi pól z np.fields=key1&fields=key2
, Co jest miłe do posiadania dla aplikacji Ajax. Ma również zerowe pokrycie testowe, co jest nieco niezwykłe w OSS.serializers.py
views.py
źródło
Skonfiguruj nową klasę serializatora stronicowania
Utwórz dynamiczny serializator
Na koniec użyj domysłów do swoich APIViews
Żądanie
Teraz, gdy żądasz zasobu, możesz dodać parametr,
fields
aby wyświetlić tylko określone pola w adresie URL./?fields=field1,field2
Możesz znaleźć przypomnienie tutaj: https://gist.github.com/Kmaschta/e28cf21fb3f0b90c597a
źródło
Możesz wypróbować Dynamic REST , który obsługuje pola dynamiczne (włączanie, wykluczanie), obiekty osadzone / wczytywane z boku, filtrowanie, porządkowanie, paginację i inne.
źródło
Taką funkcjonalność zapewniliśmy w drf_tweaks / control-over-serialized-fields .
Jeśli korzystasz z naszych serializatorów, wystarczy przekazać
?fields=x,y,z
parametr w zapytaniu.źródło
W przypadku danych zagnieżdżonych używam Django Rest Framework z pakietem zalecanym w dokumentacji , drf-flexfields
Pozwala to ograniczyć pola zwracane zarówno w obiekcie nadrzędnym, jak i podrzędnym. Instrukcje w pliku readme są dobre, tylko kilka rzeczy, na które należy uważać:
Wydaje się, że adres URL wymaga / like this „/ person /? Expand = country & fields = id, name, country” zamiast zapisanego w pliku readme „/ person? Expand = country & fields = id, name, country”
Nazewnictwo zagnieżdżonego obiektu i jego nazwa pokrewna muszą być całkowicie spójne, co w innym przypadku nie jest wymagane.
Jeśli masz „wiele”, np. Kraj może mieć wiele stanów, musisz ustawić „wiele”: Prawda w Serializatorze, jak opisano w dokumentacji.
źródło
Jeśli chcesz czegoś elastycznego, takiego jak GraphQL, możesz użyć django-restql . Obsługuje zagnieżdżone dane (zarówno płaskie, jak i iterowalne).
Przykład
Zwykłe żądanie zwraca wszystkie pola.
GET /users
Z
query
drugiej strony żądanie z parametrem zwraca tylko podzbiór pól:GET /users/?query={id, username}
Dzięki django-restql możesz uzyskać dostęp do zagnieżdżonych pól na dowolnym poziomie. Na przykład
GET /users/?query={id, username, date_joined{year}}
Dla iterowalnych pól zagnieżdżonych, np. Grupy użytkowników.
GET /users/?query={id, username, groups{id, name}}
źródło