with framework example ejemplo create python django django-rest-framework

python - example - django rest framework serializer



¿Cómo puedo registrar una sola vista(no una vista) en mi enrutador? (2)

Estoy usando el marco Django REST y he intentado crear una vista que devuelva un poco de información, así como registrarla en mi enrutador.

Tengo cuatro modelos que almacenan información, y todos ellos tienen un campo created_time . Estoy tratando de hacer una vista que devuelva los objetos más recientes (basados ​​en el created_time ) en una sola vista, donde solo se devuelven los cuatro tiempos de creación.

Entonces, una posible salida JSON de la vista se vería así

{ "publish_updatetime": "2015.05.20 11:53", "meeting_updatetime": "2015.05.20 11:32", "training_updatetime": "2015.05.20 15:25", "exhibiting_updatetime": "2015.05.19 16:23" }

También espero registrar esta vista en mi enrutador, por lo que aparece con el resto de mis puntos finales cuando se carga la raíz API.

router.register(r''updatetime'', views.UpdateTimeView)

Aquí están los cuatro modelos con los que estoy tratando de trabajar

class Publish(models.Model): user = models.ForeignKey(MyUser) name = models.CharField(max_length=50) created_time = models.DateTimeField( default=datetime.now) class Meeting(models.Model): user = models.ForeignKey(MyUser) name = models.CharField(max_length=50) file_addr = models.FileField(upload_to=get_file_path) created_time = models.DateTimeField(default=datetime.now) class Training(models.Model): user = models.ForeignKey(MyUser) name = models.CharField(max_length=50) image = models.ImageField(upload_to=get_file_path, max_length=255) created_time = models.DateTimeField(default=datetime.now) class Exhibiting(models.Model): user = models.ForeignKey(MyUser) name = models.CharField(max_length=50) file_addr = models.FileField(upload_to=get_file_path) created_time = models.DateTimeField(default=datetime.now)

¿Es posible hacer esto? ¿Y cómo se haría?


Hay una forma más de hacerlo:

urlpatterns = [ # ... url(r''^you_path/'', include(router.urls)), url(r''^you_path/you_sub_path'', views.UpdateTimeView.as_view()), # ... ]

Pero cosas como Swagger no funcionarán con eso


Los enrutadores funcionan con un ViewSet y no están diseñados para vistas normales, pero eso no significa que no pueda usarlos con una vista normal. Normalmente se usan con modelos (y un ModelViewSet ), pero se pueden usar sin ellos usando GenericViewSet (si normalmente usaría un GenericAPIView ) y ViewSet (si solo usaría un APIView ).

Para una vista de lista, los métodos de solicitud se asignan a métodos ViewSet como este

  • GET -> list(self, request, format=None)
  • POST -> create(self, request, format=None)

Para vistas detalladas (con una clave principal en la URL), los métodos de solicitud utilizan el siguiente mapa

  • GET -> retrieve(self, request, pk, format=None)
  • PUT -> update(self, request, pk, format=None)
  • PATCH -> partial_update(self, request, pk, format=None)
  • DELETE -> destroy(self, request, pk, format=None)

Entonces, si desea utilizar cualquiera de estos métodos de solicitud con su vista en su enrutador, debe anular el método de vista correcto (entonces list() lugar de get() ).

Ahora, específicamente en su caso, normalmente habría utilizado una APIView que se parecía a

class UpdateTimeView(APIView): def get(self, request, format=None): latest_publish = Publish.objects.latest(''created_time'') latest_meeting = Meeting.objects.latest(''created_time'') latest_training = Training.objects.latest(''created_time'') latest_exhibiting = Exhibiting.objects.latest(''created_time'') return Response({ "publish_updatetime": latest_publish.created_time, "meeting_updatetime": latest_meeting.created_time, "training_updatetime": latest_training.created_time, "exhibiting_updatetime": latest_exhibiting.created_time, })

El ViewSet comparable sería

class UpdateTimeViewSet(ViewSet): def list(self, request, format=None): latest_publish = Publish.objects.latest(''created_time'') latest_meeting = Meeting.objects.latest(''created_time'') latest_training = Training.objects.latest(''created_time'') latest_exhibiting = Exhibiting.objects.latest(''created_time'') return Response({ "publish_updatetime": latest_publish.created_time, "meeting_updatetime": latest_meeting.created_time, "training_updatetime": latest_training.created_time, "exhibiting_updatetime": latest_exhibiting.created_time, })

Observe los dos cambios requeridos: APIView -> ViewSet y get -> list . También actualicé el nombre para indicar que era más que una vista normal (ya que un ViewSet no se puede inicializar de la misma manera), pero eso no es obligatorio.

Entonces, con esta nueva vista, puede registrarla en el enrutador de la misma manera que cualquier otra. Necesita un base_name aquí para que se puedan generar los nombres de URL (normalmente esto se extraería del conjunto de consultas).

router.register(r''updatetime'', views.UpdateTimeViewSet, base_name=''updatetime'')

Así que ahora el updatetime final de tiempo de updatetime estará disponible en la raíz de la API y puede obtener los últimos tiempos simplemente llamando al punto final (una simple solicitud GET).