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).