如何在Django rest framework中显示来自另一个序列化器的字段

tcbh2hod  于 2022-12-01  发布在  Go
关注(0)|答案(1)|浏览(136)

我想显示额外的字段作为回应,显示类似的产品或相关产品的类别,而我在一个产品详细信息页面。例如:如果我正在查看单个产品的详细信息页面,在页面底部,相关产品列表也必须显示在那里。因此,在响应相关产品时,我想显示ProductDetailserilaizerhighest_offer_price, product_offer_discount, category_offer_discount

序列化程序.py

第一个
查看次数.py

class ProductDetailView(APIView):
    def get(self, request, category_slug, product_slug):
        try:
            single_product = Products.objects.get(
                category__slug=category_slug, slug=product_slug
            )
        except:
            raise exceptions.NotFoundError()
        serializer = ProductDetailserializer(
            single_product, context={
            "request": request, 
            }
            
        )
        return Response(serializer.data)

响应数

{
    "id": 1,
    "product_name": "Pendant 1",
    "slug": "pendant-1",
    "highest_offer_price": null,
    "category_offer_discount": null,
    "product_offer_discount": null,
    "description": [
        {
            "title": "First title",
            "description": "First description pendant 1"
        },
        {
            "title": "second title",
            "description": "second description pendant 1"
        }
    ],
    "base_price": 2500,
    "stock": 97,
    "is_available": true,
    "images": "http://127.0.0.1:8000/media/photos/products/pendant3.webp",
    "extra_images": [
        {
            "images": "http://127.0.0.1:8000/media/photos/product-images/pendant3.webp"
        },
        {
            "images": "http://127.0.0.1:8000/media/photos/product-images/pendant3_BQJRObf.webp"
        },
        {
            "images": "http://127.0.0.1:8000/media/photos/product-images/pendant3_QGmLbXC.webp"
        }
    ],
    "related_products": [
        {
            "product_name": "Pendant 2",
            "slug": "pendant-2",
            "base_price": 3500,
            "images": "http://127.0.0.1:8000/media/photos/products/pendant2.webp"
        },
        {
            "product_name": "Pendant 3",
            "slug": "pendant-3",
            "base_price": 1500,
            "images": "http://127.0.0.1:8000/media/photos/products/281031cw114n.webp"
        },
        {
            "product_name": "pendant 4",
            "slug": "pendant-4",
            "base_price": 1500,
            "images": "http://127.0.0.1:8000/media/photos/products/281031cw114n_Nxbx7lT.webp"
        }
    ]

我是新来的,我想我把它复杂化了太多,因为我已经为Product模型写了多个序列化程序。

cbeh67ev

cbeh67ev1#

如果同一个模型有多个序列化程序,并且它们之间的数据不同,那么这是非常好的。
如果您担心在不同的序列化程序上多次重写相同的代码,您可以为Products模型创建一个基本序列化程序,然后根据需要扩展它。
就像这样:

# Make a BaseProductSerializer that inherits from Modelserializer and contains all fields and methods that all Products serializers need.
class BaseProductSerializer(Modelserializer):
    product_offer_discount = SerializerMethodField()
    category_offer_discount = SerializerMethodField()
    highest_offer_price = SerializerMethodField()

    def get_product_offer_discount(self):
        return # whatever this method should do...

    def get_category_offer_discount(self):
        return # whatever this method should do...

    def get_highest_offer_price(self):
        return # whatever this method should do...

# Make a serializer for related products that inherits from BaseProductSerializer and specify the Meta data.
class RelatedProductSerializer(BaseProductSerializer):
    class Meta:
        model = Products
        fields = [
            'product_name',
            'slug',
            'base_price',
            'images',
            'highest_offer_price',
            'product_offer_discount',
            'category_offer_discount'
        ]

# Make a serializer for product details that inherits from BaseProductSerializer and add any extra fields/methods that you need.
class ProductDetailserializer(BaseProductSerializer):
    description = ProductDescription()
    extra_images = SerializerMethodField()
    related_products = SerializerMethodField()

    class Meta:
        model = Products
        fields = [
            "id",
            "product_name",
            "slug",
            "highest_offer_price",
            "category_offer_discount",
            "product_offer_discount",
            "description",
            "base_price",
            "stock",
            "is_available",
            "images",
            "extra_images",
            "related_products"
        ]

    def to_representation(self, instance):
        print('INSTANCE', instance)
        rep = super().to_representation(instance)
        rep['description'] = ProductDescriptionSerializer(instance.description, many=True).data
        return rep

    def get_related_products(self, obj):
        products= Products.objects.filter(category=obj.category).exclude(id=obj.id)
        return RelatedProductSerializer(products, many=True, context=self.context).data

    def get_extra_images(self, obj):
        images = obj.extra_images.all()
        return ProductImageSerializer(images, many=True, context=self.context).data

希望这对你有帮助。

相关问题