viewsets viewset update route queryset modelviewset get_object_or_404 framework detail decorators create django django-rest-framework

viewset - partial update django rest framework



Agregar más vistas a un enrutador o conjunto de vistas(Django-Rest-Framework) (4)

Ahora puede hacer esto con los decoradores list_route y detail_route: http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing

Por ejemplo:

from rest_framework.decorators import list_route from rest_framework.response import Response ... class MyObjectsViewSet(viewsets.ViewSet): ... @list_route() def locations(self, request): queryset = get_locations() serializer = LocationSerializer(queryset, many=True) return Response(serializer.data)

Esencialmente, estoy tratando de encontrar una buena manera de adjuntar más vistas a un enrutador sin crear un enrutador personalizado. ¿Cuál es una buena manera de lograr esto?

Aquí hay algo parecido a lo que estoy tratando de lograr. Se han cambiado los nombres de las variables y el método de ejemplo que quiero introducir está extremadamente simplificado por el bien de esta pregunta.

Enrutador

router = routers.SimpleRouter(trailing_slash=False) router.register(r''myobjects'', MyObjectViewSet, base_name=''myobjects'') urlpatterns = router.urls

ViewSet

class MyObjectsViewSet(viewsets.ViewSet): """ Provides API Methods to manage MyObjects. """ def list(self, request): """ Returns a list of MyObjects. """ data = get_list_of_myobjects() return Response(data) def retrieve(self, request, pk): """ Returns a single MyObject. """ data = fetch_my_object(pk) return Response(data) def destroy(self, request, pk): """ Deletes a single MyObject. """ fetch_my_object_and_delete(pk) return Response()

Un ejemplo de otro tipo de método que necesito incluir. (Hay muchos de estos):

def get_locations(self, request): """ Returns a list of location objects somehow related to MyObject """ locations = calculate_something() return Response(locations)

El resultado final es que la siguiente URL funcionaría correctamente y se implementaría "limpiamente".

GET example.com/myobjects/123/locations


Del enrutamiento a métodos adicionales en un ViewSet :

Creo que es posible que deba enrutar el método a mano, es decir, The Old-Fashioned Way ™.

Primero saca el método como una vista separada:

set_password_view = UserViewSet.as_view({''post'': ''set_password''})

(o tal)

Luego asigne su URL:

url(r''^users/username_available/$'', set_password_view, name-=...)

(O tal)

Hay una pregunta relacionada en SO .


La respuesta dada por mariodev arriba es correcta, siempre y cuando solo esté buscando realizar solicitudes GET .

Si desea POST a una función que está agregando a un ViewSet, necesita usar el decorador de action :

from rest_framework.decorators import action, link from rest_framework.response import Response class MyObjectsViewSet(viewsets.ViewSet): # For GET Requests @link() def get_locations(self, request): """ Returns a list of location objects somehow related to MyObject """ locations = calculate_something() return Response(locations) # For POST Requests @action() def update_location(self, request, pk): """ Updates the object identified by the pk """ location = self.get_object() location.field = update_location_field() # your custom code location.save() # ...create a serializer and return with updated data...

Luego, /myobjects/123/update_location/ un POST a una URL con formato como: /myobjects/123/update_location/

http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing tiene más información si está interesado.


Usted define el método como lo hace ahora, pero necesita usar la misma url como nombre del método y agregar el decorador de enlaces, así que para

/myobjects/123/locations/

Usted agrega método como este

@link(permission_classes=[...]) def locations(self, request, pk=None): ...

y el enrutador lo recogerá automáticamente.