简体   繁体   中英

How to join two related models in one serializer in django

I was trying to create an API for the Product model in which I want to include multiple images for a single product but don't want to use ManytoMany relation as I want Admin to add separate Images for all products but I am stuck at this point that how can I create a serializer for the same so that I can get expected JSON output from that.

my models code and expected JSON is given below.

Thanks in advance!

MODELS:

class Product(models.Model):
    title = models.CharField(blank=True,null=False,max_length=100)
    
class ProductImage(models.Model):
    product = models.ForeignKey(to='products.Product', on_delete=models.CASCADE, default=None)
    image = models.ImageField(upload_to='images/product_inmages', null=False, blank=False)
    def __str__(self):
        return self.product.title

EXPECTED RESULT FROM PRODUCT SERIALIZER:

[
{
    title:"title 1",
    product_images:[
    "media/image1.png",
    "media/image2.png",
    "media/image3.png"
    ]
},
{
    title:"title 2",
    product_images:[
    "media/image4.png",
    "media/image5.png",
    "media/image6.png"
    ]
}
]

I haven't tested this, but it might be a start:

# serializers.py
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from . import products 

class ProductSerializer(ModelSerializer):
    product_images = SerializerMethodField()
    
    def get_product_images(self, product):
        return product.productimage_set.values_list('image', flat=True)

    class Meta:
        model = products.Product
        fields = ['title', 'product_images']

If you want product_images to be writable it might be easiest to use two Serializers:

# serializers.py
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from . import products 

class ProductImageSerializer(ModelSerializer):
    class Meta:
        model = products.ProductImage
        fields = ['image']

class ProductSerializer(ModelSerializer):
    product_images = ProductImageSerializer(source='productimage_set', many=True)

    class Meta:
        model = products.Product
        fields = ['title', 'product_images']

EDIT: You might also want to include the field 'id' for all of these serializers.

I have found the answer:

In the model, we have to add related_name of product in ProductImage

MODEL:

class Product(models.Model):
    title = models.CharField(blank=True,null=False,max_length=100)
    
class ProductImage(models.Model):
    product = models.ForeignKey(to='products.Product', on_delete=models.CASCADE, default=None,related_name='images')
    image = models.ImageField(upload_to='images/product_inmages', null=False, blank=False)
    def __str__(self):
        return self.product.title

And for the serializer, we can use the nested serializer in the following way

SERIALIZERS:

class ProductImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductImage
        fields = '__all__' 
 

class ProductSerializer(serializers.ModelSerializer):
    images = ProductImageSerializer(many=True, read_only=True)
    class Meta:
        model = Product
        fields = '__all__' 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM