如何在我的 "UsuarioSerializer" Django 中获取 "ProductoSeralizer" 的列表

How can I get a list of "ProductoSeralizer" in my "UsuarioSerializer" Django

我需要每个用户订购的产品,比如在“UsuarioSerializer”中我想放一个字段“productos”,它是“ProductoSeralizer”的列表,但是模型“Usuario”没有与“ProductoSeralizer”直接相关,所以当我尝试时它给我一个错误,如何解决这个问题?我需要这样的 JSON 响应:

[
    {
        "id": 1,
        "cantidad_de_productos": 12,
        "fecha": "2021-03-21T06:26:26.981487Z",
        "correo": "user1@email.com",
        "password": "pass",
        "productos" : [
            {},
            {}
        ]
    },
    {
        "id": 2,
        "cantidad_de_productos": 0,
        "fecha": "2021-03-21T06:26:56.700399Z",
        "correo": "user2@email.com",
        "password": "pass",
        "productos" : [
            {},
            {}
        ]
    }
]

models.py

class Entidad(models.Model):
    fecha = models.DateTimeField(auto_now=True)
    class Meta:
        abstract = True

class Usuario(Entidad):
    correo = models.EmailField(unique=True)
    password = models.CharField(max_length=20)

    def __str__(self) -> str:
        return self.correo

class Orden(Entidad):
    solicitante = models.ForeignKey(Usuario, related_name='ordenes', on_delete=models.CASCADE)
    productos = models.ManyToManyField('Producto', through='Detalle')

class Producto(Entidad):
    nombre = models.CharField(max_length=20, unique=True)
    ordenes = models.ManyToManyField('Orden', through='Detalle')

    def __str__(self) -> str:
        return self.nombre

class Detalle(Entidad):
    cantidad = models.PositiveIntegerField()

    orden = models.ForeignKey(Orden, related_name='detalles', on_delete=models.CASCADE)
    producto = models.ForeignKey(Producto, related_name='detalles', on_delete=models.CASCADE)

serializers.py

class ProductoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Producto
        fields = '__all__'

class ProductosUsuarioSerializer(serializers.ModelSerializer):
    cantidad = models.IntegerField()
    class Meta:
        model = Producto
        fields = '__all__'

class DetalleOrdenSerializer(serializers.ModelSerializer):
    class Meta:
        model = Detalle
        exclude = ['orden']

class OrdenSerializer(serializers.ModelSerializer):
    detalles = DetalleOrdenSerializer(many=True)
    class Meta:
        model = Orden
        exclude = ['productos']

    def create(self, validated_data):
        detalles_data = validated_data.pop('detalles')
        orden = Orden.objects.create(**validated_data)
        for detalle_data in detalles_data:
            Detalle.objects.create(orden=orden, **detalle_data)
        return orden

class DetalleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Detalle
        fields = '__all__'

class UsuarioSerializer(serializers.ModelSerializer):
    cantidad_de_productos = serializers.IntegerField()

    class Meta:
        model = Usuario
        fields = '__all__'

views.py

class Usuario(ListCreateAPIView):
    queryset = Usuario.objects.annotate(cantidad_de_productos=Coalesce(Sum('ordenes__detalles__cantidad'), 0))
    serializer_class = UsuarioSerializer

您可以向序列化程序添加一个 SerializerMethodField 字段。

from models import Orden, Producto


class UsuarioSerializer(serializers.ModelSerializer):
    cantidad_de_productos = serializers.IntegerField()
    productos = serializers.SerializerMethodField()

    class Meta:
        model = Usuario
        fields = '__all__'

    def get_productos(self, obj):
        ordenes = Orden.objects.filter(solicitante=obj.id)
        # get all product ids from orders
        product_ids = [product.id for orden in ordenes for product in orden.productos.all()]
        # find products (It does not matter if there are duplicate ids, it will not repeat products.)
        user_products = Producto.objects.filter(id__in=product_ids)
        # format the response
        products = [{
            'id': product.id,
            'name': product.nombre
        } for product in user_products]
        return products

每个返回的用户都会调用该方法