返回带有序列化程序列表的响应Django REST Framework

Enr*_*res 5 python django django-rest-framework

I'm coding some backend software for a second-hand selling app using Django and DjangoRestFramework. Right now, I'm trying to send a Response object that contains a list of products, but I seem not to be able to return an actual list of products, as I'm getting an error saying

ListSerializer is not JSON serializable.
Run Code Online (Sandbox Code Playgroud)

I've tried both using the serializer constructor like this:

ProductoSerializer(products, many=True)
Run Code Online (Sandbox Code Playgroud)

And by creating a list of ProductoSerializer.data and then creating the Response object with that.

Here's the serializers that I'm using:

class UserSerializer(serializers.HyperlinkedModelSerializer):
    ciudad = serializers.SerializerMethodField()
    conectado = serializers.SerializerMethodField()
    class Meta:
        model = Usuario
        fields = ('uid', 'nombre', 'ciudad', 'conectado')
    def get_ciudad(self, obj):
        geolocator = Nominatim(user_agent="bookalo")
        location = geolocator.reverse(str(obj.latitud_registro) + ',' + str(obj.longitud_registro))
        return location.raw['address']['city']

    def get_conectado(self, obj):
        ahora = timezone.now()
        result = relativedelta(ahora, obj.ultima_conexion)
        return result.days == 0 and result.hours == 0 and result.months == 0 and result.years == 0 and result.minutes < 5

class TagSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Tag
        fields = ('nombre')

class MultimediaSerializer(serializers.HyperlinkedModelSerializer):
    contenido_url = serializers.SerializerMethodField()
    class Meta:
        model = ContenidoMultimedia
        fields = ('contenido_url', 'orden_en_producto')

    def get_contenido_url(self, obj):
        return obj.contenido.url

class MiniProductoSerializer(serializers.HyperlinkedModelSerializer):
    contenido_multimedia = serializers.SerializerMethodField()
    class Meta:
        model = Producto
        fields = ('nombre', 'precio', 'estado_venta', 'contenido_multimedia')

    def get_contenido_multimedia(self, obj):
        contenido = ContenidoMultimedia.objects.get(producto=obj.pk, orden_en_producto=0)
        return MultimediaSerializer(contenido)

class ProductoSerializer(serializers.HyperlinkedModelSerializer):
    vendido_por = UserSerializer(read_only=True)
    tiene_tags = TagSerializer(many=True, read_only=True)
    contenido_multimedia = serializers.SerializerMethodField()
    valoracion_media_usuario = serializers.SerializerMethodField()
    class Meta:
        model = Producto
        fields = ('nombre', 'precio', 'estado_producto', 'estado_venta', 'latitud', 'longitud', 'tipo_envio', 'descripcion', 'vendido_por', 'tiene_tags', 'num_likes', 'contenido_multimedia')

    def get_contenido_multimedia(self, obj):
        contenido = ContenidoMultimedia.objects.filter(producto=obj.pk).order_by('orden_en_producto')
        return MultimediaSerializer(contenido, many=True)

    def get_valoracion_media_usuario(self, obj):
        return Usuario.objects.get(pk=obj.vendido_por).media_valoraciones

class ValidacionEstrellaSerializer(serializers.HyperlinkedModelSerializer):
    usuario_que_valora = UserSerializer(read_only=True)
    producto_asociado = serializers.SerializerMethodField()
    class Meta:
        model = ValidacionEstrella
        fields = ('estrellas', 'comentario', 'timestamp', 'usuario_que_valora', 'producto_asociado')

    def get_producto_asociado(self, obj):
        producto = Producto.objects.get(pk=obj.producto)
        return MiniProductoSerializer(producto)

class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
    usuario_valorado_estrella = serializers.SerializerMethodField()
    productos_favoritos = serializers.SerializerMethodField()
    class Meta:
        model = Usuario
        fields = ('uid', 'nombre', 'esta_baneado', 'usuario_valorado_estrella', 'producto_del_usuario')

    def get_usuario_valorado_estrella(self, obj):
        validaciones = ValidacionEstrella.objects.filter(usuario_valorado=obj.pk).order_by('-timestamp')
        return ValidacionEstrellaSerializer(validaciones, many=True, read_only=True)

    def get_productos_favoritos(self, obj):
        favoritos = Producto.objects.filter(le_gusta_a__in=[obj.pk])
        return ProductoSerializer(favoritos, many=True, read_only=True)

class ReportSerializer(serializers.HyperlinkedModelSerializer):
    #usuario_reportado = serializers.SerializerMethodField()
    usuario_reportado = UserSerializer(read_only=True)
    class Meta:
        model = Report
        fields = ('usuario_reportado', 'causa')
Run Code Online (Sandbox Code Playgroud)

And here's the views.py function that I'm trying to code:

@api_view(['POST'])
@permission_classes((permissions.AllowAny,))
def SearchProduct(request, format=None):
    if request.method != 'POST':
        return Response(status=status.HTTP_400_BAD_REQUEST)
    preposiciones = ['a','ante','bajo','cabe','con','contra','de','desde','en','entre',
    'hacia','hasta','para','por','segun','sin','so','sobre','tras']
    try:
        search = request.POST.get('busqueda')
    except:
        return Response(status=status.HTTP_404_NOT_FOUND)
    products = Producto.objects.none()
    for word in search.split():
        if word not in preposiciones:
            productos_palabra = Producto.objects.filter(nombre__contains=word)
            products = products | productos_palabra
    products.distinct()
    product_list = []
    for prod in products:
        product_list.append(ProductoSerializer(prod).data)
    return Response({'productos': product_list}, status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

I'm using a request object because I also have to server a WebPage, and not only a mobile app, with the same function (the webpage part is still not coded though).

It should return all the products that contain at least one of the words from the user's search, and it all should be structured based on the ProductoSerializer object, but for some reason, it's outputting that error and I'm not quite sure how to fix it.

Thanks in advance, and if you need any extra information which I've missed, please do ask for it... It's been a long day and I probably missed something.

Ser*_*ach 3

似乎当您使用时SerializerMethodField返回序列化器实例,但不是data

例如:

contenido_multimedia = serializers.SerializerMethodField()


def get_contenido_multimedia(self, obj):
        contenido = ContenidoMultimedia.objects.filter(producto=obj.pk).order_by('orden_en_producto')
        return MultimediaSerializer(contenido, many=True).data  # <-- here try to add .data
Run Code Online (Sandbox Code Playgroud)

所有方法都应该更改它SerializerMethodField