tutorial restframework modelviewset framework espaƱol django django-rest-framework

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