restframework - pip install rest framework django
Django resto marco modelo serializadores-leer anidados, escribir plano (3)
Tengo una situación en la que mi cliente está intentando escribir una representación que incluye una lista de fk''s
{
languages: [1]
last_name: "Beecher"
settings: 1
state: "NY"
}
Pero al leerlo, me gustaría tener una representación anidada para reducir los viajes de ida y vuelta
{
languages: [{id:1, created:2013-07-21T01:38:33.569Z, modified:2013-07-21T01:38:33.569Z, language:testing}]
last_name: "Beecher"
settings: {
created: "2013-07-20T22:04:17.998Z"
email_blog: false
email_booking_accepted_denied: false
email_booking_request: false
email_friend_joined: false
email_groups_added_network: false
email_new_review: false
email_news: false
email_upcoming_booking_remind: false
id: 1
mobile_booking_accepted_denied: false
mobile_booking_request: false
mobile_friend_joined: false
mobile_groups_added_network: false
mobile_new_review: false
mobile_upcoming_booking_remind: false
modified: "2013-07-20T22:04:18.000Z"
user: 1
}
state: "NY"
}
La lectura no es un problema usando un serializador de modelo y profundidad = 1, pero al intentar escribir se produce un error "ValueError (''la instancia debe ser un queryset u otro iterable con many = True'')" Al intentar verificar muchos campos relacionados para iter
Por el contrario, desactivar la profundidad hace que la escritura funcione como me gustaría, pero leer no es bueno.
¿Hay algo que estoy perdiendo por completo aquí? Parece que debería ser un cambio simple, pero solo puedo hacer que uno u otro funcione
Gracias a las publicaciones anteriores, get_serializer_class
por una solución similar basada en get_serializer_class
para esto.
También quería poder cambiar la clase del serializador según el método.
Primero, agregué un atributo a la clase de vista con métodos de solicitud de mapeo de diccionario a las clases de serializador.
serializer_classes = {
''GET'': NestedSerializer,
''POST'': FlatSerializer
}
Luego, definí una mezcla para usar donde quiero este comportamiento.
class SwappableSerializerMixin(object):
def get_serializer_class(self):
try:
return self.serializer_classes[self.request.method]
except AttributeError:
logger.debug(''%(cls)s does not have the required serializer_classes''
''property'' % {''cls'': self.__class__.__name__})
raise AttributeError
except KeyError:
logger.debug(''request method %(method)s is not listed''
'' in %(cls)s serializer_classes'' %
{''cls'': self.__class__.__name__,
''method'': self.request.method})
# required if you don''t include all the methods (option, etc) in your serializer_class
return super(SwappableSerializerMixin, self).get_serializer_class() es
Lo más simple que se me ocurre es anular get_serializer_class()
en su vista para que POST / PUT devuelva un serializador modificado que no especifica el parámetro de profundidad y utiliza un campo PrimaryKeyRelatedField para sus languages
.
Tuve el mismo problema y parece que muchos otros lo tienen también. La respuesta de Carlton Gibson en realidad me llevó a mi solución hacky. Terminé usando un ModelSerializer con el conjunto de profundidad y creé la siguiente mezcla para usar en las vistas.
class ReadNestedWriteFlatMixin(object):
"""
Mixin that sets the depth of the serializer to 0 (flat) for writing operations.
For all other operations it keeps the depth specified in the serializer_class
"""
def get_serializer_class(self, *args, **kwargs):
serializer_class = super(ReadNestedWriteFlatMixin, self).get_serializer_class(*args, **kwargs)
if self.request.method in [''PATCH'', ''POST'', ''PUT'']:
serializer_class.Meta.depth = 0
return serializer_class