Сепарация ответа в DRF
Я возвращаю сводку заказов, в которой order_total, order_number ,quantity and the payment
повторяется, но я хочу, чтобы она была показана только один раз. Например, все товары должны быть только одни во вложенном ответе сериализатора, а другие должны быть показаны по одному без повторений
#Serializer
class OrderSummarySerializer(ModelSerializer):
product = ProductSerializer()
payment = PaymentSerializer()
order_number = SerializerMethodField()
order_total = SerializerMethodField()
class Meta:
model = OrderProducts
fields = ["order_number", "payment", "product", "quantity", "order_total"]
def get_order_total(self, obj):
return obj.order.order_total
def get_order_number(self, obj):
print(obj)
return obj.order.order_number
#Просмотры
class OrderSummary(APIView):
def get(self, request):
try:
order_number = request.GET.get("order_number")
orders = Orders.objects.get(user=request.user, order_number=order_number)
order_summary = OrderProducts.objects.filter(
user=request.user, order__order_number=order_number, is_ordered=True
)
context = {
"request": request,
}
serializer = OrderSummarySerializer(
order_summary, many=True, context=context
)
return Response(serializer.data, status=status.HTTP_200_OK)
except Exception as e:
print(e)
return Response(
{"error": "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST
#Ответ я получаю
[
{
"order_number": "ypVtT1",
"payment": {
"payment_method": "cod",
"amount_paid": "",
"status": "Pending",
"created_at": "2022-12-16T16:46:30.915646+05:30"
},
"product": {
"id": 1,
"product_name": "Pendant1",
"sub_product_name": null,
"slug": "pendant-1",
"highest_offer_price": 250.0,
"category_offer_discount": 1250.0,
"product_offer_discount": 2250.0,
"base_price": 2500,
"stock": 5,
"is_available": true,
"product_image": "http://127.0.0.1:8000/media/photos/products/pendant3.webp"
},
"quantity": 1,
"order_total": 2170.0
},
{
"order_number": "ypVtT1",
"payment": {
"payment_method": "cod",
"amount_paid": "",
"status": "Pending",
"created_at": "2022-12-16T16:46:30.915646+05:30"
},
"product": {
"id": 2,
"product_name": "Pendant2",
"sub_product_name": null,
"slug": "pendant-2",
"highest_offer_price": 1750.0,
"category_offer_discount": 1750.0,
"product_offer_discount": null,
"base_price": 3500,
"stock": 11,
"is_available": true,
"product_image": "http://127.0.0.1:8000/media/photos/products/pendant2.webp"
},
"quantity": 1,
"order_total": 2170.0
}
]
# Ответ, который я хочу получить:
[
{
"order_number": "ypVtT1",
"quantity": 1,
"order_total": 2170.0
"payment": {
"payment_method": "cod",
"amount_paid": "",
"status": "Pending",
"created_at": "2022-12-16T16:46:30.915646+05:30"
},
"product": {
"id": 1,
"product_name": "Pendant1",
"sub_product_name": null,
"slug": "pendant-1",
"highest_offer_price": 250.0,
"category_offer_discount": 1250.0,
"product_offer_discount": 2250.0,
"base_price": 2500,
"stock": 5,
"is_available": true,
"product_image": "http://127.0.0.1:8000/media/photos/products/pendant3.webp"
},
},
"product": {
"id": 2,
"product_name": "Pendant2",
"sub_product_name": null,
"slug": "pendant-2",
"highest_offer_price": 1750.0,
"category_offer_discount": 1750.0,
"product_offer_discount": null,
"base_price": 3500,
"stock": 11,
"is_available": true,
"product_image": "http://127.0.0.1:8000/media/photos/products/pendant2.webp"
},
}
]
Это из-за использования ModelSerializer
. Должен ли я сделать отдельный сериализатор для отдельных вещей, чтобы показать их и вызвать его на текущем сериализаторе?
Вы можете создать Order Serializer, который содержит OrderSummary, вот так:
class OrderSerializer(serializer.ModelSerializer):
summary = serializer.SerializerMethodField()
class Meta:
model = Order
fields = ["order_number", "summary", "order_total"]
def get_summary(self, obj):
order_summary = OrderProducts.objects.filter(
user=obj.user, order__order_number=obj.order_number, is_ordered=True
) # consider using reverse query in Django queryset
serializer = OrderSummarySerializer(
order_summary, many=True, context=self.context
)
return serializer.data
Затем используйте его в представлениях следующим образом:
class OrderSummary(APIView):
def get(self, request):
try:
order_number = request.GET.get("order_number")
order = Order.objects.get(user=request.user, order_number=order_number)
return OrderSerializer(instance=order, context={'request':request}).data
except:
....