¿Cómo puedo usar serializador anidado dentro del mismo serializador?
class UserViewSerializer(DynamicFieldsMixin,serializers.ModelSerializer):
followers_set = UserViewSerializer(required=False,many=True)
class Meta:
model = User
fields = ('id','email','username','password','followers_set')
depth = 2
¿Hay de todos modos que pueda usar esta función sin recibir este error?
followers_set = UserViewSerializer(source='follows',required=False,many=True)
NameError: name 'UserViewSerializer' is not defined
Traté de Serializer MétodoField pero entonces no puedo usar la opción de profundidad allí
following_set = serializers.SerializerMethodField()
def get_following_set(self, user):
return UserViewSerializer(User.objects.filter(follows__author=user), many=True).data
usando Serializer Método Campo me da error de:
RecursionError at /api/users/
maximum recursion depth exceeded
¿Puede alguien ayudarme, por favor?
Pregunta hecha hace 3 años, 4 meses, 26 días - Por compilercaptain7dab
3 Respuestas:
-
La forma más simple de manejar esto es hacer tres serializadores: uno sin un
followers_set
, uno con unfollowers_set
que utiliza el anterior, y uno que utiliza el segundo modelo, por lo que:# no followers_set class UserViewSerializer0(DynamicFieldsMixin,serializers.ModelSerializer): class Meta: model = User fields = ('id','email','username') # followers_set, but only depth 1 class UserViewSerializer1(DynamicFieldsMixin,serializers.ModelSerializer): followers_set = UserViewSerializer0(source='follows',required=False,many=True) class Meta: model = User fields = ('id','email','username') # followers_set, with depth 2 class UserViewSerializer(DynamicFieldsMixin,serializers.ModelSerializer): followers_set = UserViewSerializer1(source='follows',required=False,many=True) class Meta: model = User fields = ('id','email','username')
Esto también es más seguro, ya que no se puede definir bucles recursivos, a menos que trabaje con
SerializerMethodField
, que no es una buena idea si agregas serializadores adicionales.Sin embargo, podría ser mejor no ir a la profundidad dos, pero aferrarse a la profundidad uno. Generará grandes respuestas ya, hará que la creación de objetos sea más engorrosa, y resultará en muchas consultas adicionales.
Respondida el Dec 20, 2020 a las 14:43 - por debugdynamob312
Votos positivos: 0 | Votos negativos: 0 -
Para resolver este problema, puedes utilizar la función
SerializerMethodField
en conjunto con la opcióndepth
en el serializador principal. Aquí tienes un ejemplo de cómo podrías modificar tu código para lograr esto:python class NestedUserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'email', 'username') class UserViewSerializer(serializers.ModelSerializer): followers_set = serializers.SerializerMethodField() class Meta: model = User fields = ('id', 'email', 'username', 'password', 'followers_set') depth = 2 def get_followers_set(self, user): followers = user.follows.all() return NestedUserSerializer(followers, many=True).data
En este ejemplo, creamos un nuevo serializador
NestedUserSerializer
para representar un usuario de manera más simple y menos profunda. Luego, en el serializador principalUserViewSerializer
, utilizamosSerializerMethodField
en lugar de anidar el mismo serializador. En el métodoget_followers_set
, obtenemos los seguidores del usuario y los serializamos utilizandoNestedUserSerializer
.De esta forma, evitamos problemas de recursión y podemos utilizar la opción
depth
en el serializador principal. ¡Espero que esta solución te sea útil! Si tienes alguna otra pregunta, ¡estaré encantado de ayudarte!Respondida el Dec 21, 2020 a las 14:44 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Para usar un serializador anidado dentro del mismo serializador, debes definir el serializador anidado antes de definir el serializador principal.
Aquí tienes un ejemplo corregido de tu código:
python class UserViewSerializer(DynamicFieldsMixin, serializers.ModelSerializer): class Meta: model = User fields = ('id','email','username','password','followers_set') depth = 2 class FollowerViewSerializer(DynamicFieldsMixin, serializers.ModelSerializer): class Meta: model = User fields = ('id','email','username') followers_set = FollowerViewSerializer(required=False,many=True)
En este ejemplo, he definido
FollowerViewSerializer
antes de definirUserViewSerializer
. Esto asegura queUserViewSerializer
pueda acceder a la definición deFollowerViewSerializer
.También he eliminado la opción
source
defollowers_set
enUserViewSerializer
, ya que no es necesaria cuando el campo es un serializador anidado.Ten en cuenta que
depth = 2
significa que el serializador anidado se serializará hasta una profundidad de 2 niveles. Si deseas serializar el serializador anidado a una profundidad mayor, puedes aumentar el valor dedepth
.Respondida el Dec 21, 2020 a las 14:48 - por Gemini
Votos positivos: 0 | Votos negativos: 0