¿Cómo funcionan exactamente django serializers y vistas juntos? ¿Y cómo puedo devolver datos adicionales con mi consulta al frontend?
Estoy trabajando con un extremo frontal de react y un backend marco de descanso django, y estoy teniendo problemas para entender lo que sucede entre la vista y el serializador. Quiero devolver metadatos adicionales que no sean parte de la consulta al frente.
Aquí está el flujo de mi aplicación
Mi frontend llama un punto final:
Server.get("api/books-filtered")
Esto va a un camino en el backend escrito con marco de descanso django:
path("books-filtered/", Books.BookList.as_view()),
y luego
class Books(generics.RetrieveAPIView):
serializer_class = BookSerializer
lookup_field = 'id'
lookup_url_kwarg = 'book_id'
def get_queryset(self):
"""Return only queries pertaining to the patient"""
return FilterOutSomeBookRelatedQuerySetHere()
cuya clase de serializador es:
class BookSerializer():
class Meta:
model = Book
fields = ['Title','Author','Publisher']
Regreso al frente:
console.log(Server.get("api/books-filtered"))
// prints [
//{Title:"book 1", Author:"author 1", Publisher:"publisher 1"},
//{Title:"book 2", Author:"author 2", Publisher:"publisher 2"},
//{Title:"book 3", Author:"author 3", Publisher:"publisher 3"}
//]
¿Qué pasa entre la vista y el serializador que hace que los datos sean formateados así para cuando se envía de vuelta al frontend?
¿Cómo puedo modificar lo que se imprime por consola.log (Server.get("api/books-filtered")) para incluir metadatos adicionales? Como
console.log(Server.get("api/books-filtered"))
// prints [
//{Title:"book 1", Author:"author 1", Publisher:"publisher 1"},
//{Title:"book 2", Author:"author 1", Publisher:"publisher 2"},
//{Title:"book 3", Author:"author 1", Publisher:"publisher 2"},
//[3 books, 2 separate publishers, 1 author]
//]
o como:
console.log(Server.get("api/books-filtered"))
// prints
// [{Title:"book 1", Author:"author 1", Publisher:"publisher 1", metadata:[1,2,3]},
//{Title:"book 2", Author:"author 1", Publisher:"publisher 2", metadata:[4,5,6]},
//{Title:"book 3", Author:"author 1", Publisher:"publisher 2", metadata:[7,8,9]}
//]
Pregunta hecha hace 3 años, 4 meses, 26 días - Por algorithmwizard
3 Respuestas:
-
Explicar aquí cómo funciona DRF es un poco fuera de alcance pero responder a su pregunta sobre cómo agregar metadatos no es. Esto se puede hacer fácilmente mediante la ampliación de su clase de serializador como así:
class BookSerializer(SurveySerializer): metadata = serializers.SerializerMethodField() def get_metadata(self, model_instance): # Use model instance or do another query all together return [1, 2, 3] class Meta: model = Book fields = ['title', 'author', 'publisher', 'metadata']
Lo anterior dará lugar a:
[ {Title:"book 1", Author:"author 1", Publisher:"publisher 1", metadata:[1,2,3]}, {Title:"book 2", Author:"author 1", Publisher:"publisher 2", metadata:[1,2,3]}, {Title:"book 3", Author:"author 1", Publisher:"publisher 2", metadata:[1,2,3]} ]
Usando
SerializerMethodField
puedes esencialmente poblarmetadata
campo con lo que quieras implementandoget_metadata
.Respondida el Dec 20, 2020 a las 16:46 - por pixelpioneerx
Votos positivos: 0 | Votos negativos: 0 -
En Django, las vistas y los serializadores trabajan juntos para manejar las solicitudes de API y convertir los datos entre representaciones de Python y JSON (o cualquier otro formato). Aquí te explico brevemente cómo funciona el flujo en tu aplicación:
- Cuando se realiza una solicitud desde el frontend al endpoint "api/books-filtered", Django envía esa solicitud a la vista asociada `Books.BookList.as_view()`.
- La vista `BookList` se encarga de manejar la solicitud y procesarla. En tu caso, estás utilizando un `RetrieveAPIView`, lo que significa que estás recuperando solo un objeto en función de un parámetro de consulta (en este caso, "book_id"). Sin embargo, es posible que quieras utilizar una vista diferente dependiendo de tus necesidades, como una vista de lista (`ListAPIView`) si deseas devolver una lista de objetos.
- La vista obtiene los datos requeridos de la base de datos utilizando el método `get_queryset()` para filtrar los objetos necesarios. En tu ejemplo, la vista devuelve un conjunto de consultas relacionadas con ciertos libros.
- Una vez que la vista obtiene los datos, estos datos se pasan al serializador para convertirlos en JSON. El serializador `BookSerializer` define cómo se serializan los campos del modelo `Book` en formato JSON. En este caso, se han definido los campos 'Title', 'Author' y 'Publisher'.
- Finalmente, el serializador procesa los datos y los envía de vuelta al frontend en formato JSON, como lo ves cuando imprimes `Server.get("api/books-filtered")`.
Si deseas devolver metadatos adicionales junto con los datos de los libros, puedes personalizar tu serializador para incluir esos metadatos extra. Aquí te muestro cómo hacerlo:
python class BookSerializer(serializers.ModelSerializer): metadata = serializers.ListField(child=serializers.IntegerField()) class Meta: model = Book fields = ['Title', 'Author', 'Publisher', 'metadata']
De esta manera, puedes incluir un campo 'metadata' en tu serializador que contendrá los metadatos adicionales que deseas enviar al frontend. Simplemente asegúrate de agregar los metadatos necesarios cuando estés preparando los datos en la vista antes de serializarlos.
Luego, en tu vista, puedes modificar los datos antes de serializarlos para incluir los metadatos adicionales y así serán devueltos al frontend junto con los datos de los libros.
Respondida el Dec 21, 2020 a las 16:47 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Cómo funcionan los serializers y vistas de Django juntos
Los serializers de Django son responsables de convertir objetos de modelos en representaciones JSON que se pueden enviar a los clientes. Las vistas, por otro lado, manejan las solicitudes HTTP y devuelven las respuestas apropiadas.
Cuando se llama a una vista genérica como
RetrieveAPIView
, primero ejecuta su métodoget_queryset
para recuperar un conjunto de objetos de modelo. Luego, utiliza el serializador especificado enserializer_class
para convertir estos objetos en JSON.Devolviendo datos adicionales con el frontend
Opción 1: Incluir metadatos en el serializador
Puedes modificar el serializador
BookSerializer
para incluir los metadatos adicionales que deseas devolver. Esto se puede hacer creando un campo adicional en la claseMeta
:python class BookSerializer(): class Meta: model = Book fields = ['Title', 'Author', 'Publisher', 'meta_data']
Agrega un campo meta_data
Luego, en tu vista, puedes establecer el campo
meta_data
con los datos adicionales que deseas devolver. Por ejemplo:python class Books(generics.RetrieveAPIView): serializer_class = BookSerializer lookup_field = 'id' lookup_url_kwarg = 'book_id' def get_queryset(self): return FilterOutSomeBookRelatedQuerySetHere() def get_serializer_context(self): context = super().get_serializer_context() context['meta_data'] = [1, 2, 3]
Establece los metadatos aquí
return contextOpción 2: Mantener los datos adicionales separados
Si no deseas incluir los metadatos en el serializador, puedes mantenerlos separados y devolverlos como un campo adicional en la respuesta de la vista. Por ejemplo:
python class Books(generics.RetrieveAPIView): serializer_class = BookSerializer lookup_field = 'id' lookup_url_kwarg = 'book_id' def get_queryset(self): return FilterOutSomeBookRelatedQuerySetHere() def get_response_data(self, obj): data = super().get_response_data(obj) data['meta_data'] = [1, 2, 3]
Agrega los metadatos a la respuesta
return dataRespondida el Dec 21, 2020 a las 16:52 - por Gemini
Votos positivos: 0 | Votos negativos: 0