Search code examples
djangodjango-modelsdjango-rest-frameworkmany-to-many

Django Rest Framework Get Additional related fields in one to many relation


Here's the problem Products have multiple sizes which is many to many relation

Products

|-------|---------|
|   ID  |  Title  |
|-------|---------|

Sizes

|-------|---------|
|   ID  |  Title  |
|-------|---------|

Size Through

|------|--------------|-----------|---------|
|  ID  |  Product ID  |  Size ID  |  Stock  |
|------|--------------|-----------|---------|

I manage to get sizes in my product api using Django Rest Framework but i don't know how to get stock information as well. here is the code I've

class SizeSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (
            'id',
            'title',
        )
        model = Size



class ProductsSerializer(serializers.ModelSerializer):
    sizes = SizeSerializer(many=True)

    class Meta:
        fields = (
            'url',
            'id',
            'title',
            "sizes",
        )
        model = Products

I would appreciate any help in this problem

Models

class Products(models.Model):
    title = models.CharField(max_length=125)
    sizes = models.ManyToManyField(Size, blank=True, through='SizeThrough')

    class Meta:
        verbose_name_plural = 'Products'
        verbose_name = 'Product'

    def __str__(self):
        return self.title

class SizeThrough(models.Model):
    size = models.ForeignKey(Size, on_delete=models.CASCADE)
    product = models.ForeignKey(Products, on_delete=models.CASCADE)
    stock = models.BooleanField(null=False, default=1)

class Size(models.Model):
    title = models.CharField(max_length=20)

    def __str__(self):
        return self.title

Solution

  • you should get Size through SizeThrough(you are trying the opposite):

    class SizeSerializer(serializers.ModelSerializer):
        class Meta:
            fields = (
                'id',
                'title',
            )
            model = Size
    
    
    class SizeThroughSerializer(serializers.ModelSerializer):
        size = SizeSerializer()
        class Meta:
            fields = (
                'stock',
                'size',
            )
            model = SizeThrough
    
    
    class ProductsSerializer(serializers.ModelSerializer):
        sizes_info = SizeThroughSerializer(source='sizethrough_set', many=True)
    
        class Meta:
            fields = (
                'url',
                'id',
                'title',
                "sizes_info",
            )
            model = Products