如何在我的 "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
每个返回的用户都会调用该方法
我需要每个用户订购的产品,比如在“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
每个返回的用户都会调用该方法