Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework Nested Serializers

I am currently having trouble executing two layered nesting with Django rest framework. I have read the DRF docs with nested relationships here http://www.django-rest-framework.org/api-guide/relations/ and have successfully done the first layer which is to show styles with many colors in JSON. Not sure how to chain another layer though. Any help would be appreciated. Thanks in advance!

The current output looks like this:

[{
    "name": "AAA123",
    "colors": [
        {
            "name": "White"
        }
    ]
},
{
    "name": "BBB222",
    "colors": [
        {
            "name": "White"
        },
        {
            "name": "Pink"
        },
        {
            "name": "Blue"
        }
    ]
}]

The wanted output should be like this:

[{
    "name": "AAA123",
    "colors": [
        {
            "name": "White",
            "sizes": [{name: "S"}, {name: "M"}]
        }
    ]
},
{
    "name": "BBB222",
    "colors": [
        {
            "name": "White",
            "sizes": [{name: "XS"}, {name: "S"}]
        },
        {
            "name": "Pink"
            "sizes": [{name: "XL"}, {name: "XXL"}]
        },
        {
            "name": "Blue"
            "sizes": [{name: "L"}, {name: "XL"}]
        }
    ]
}]

Specifically, I would like to show that each style has a set of colors attributed to it, and each style-color combination has a set of sizes attributed to it.

Below is my current serializers.py and models.py I've used the intermediate table because I plan to add further complexities in the future (e.g. in style-color I would like to attach location of the colored picture and in style-color-size, I will attach measurements)

serializers.py

class ColorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Color
        fields = ['name']


class SizeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Size
        fields = ['name']


class StyleSerializer(serializers.ModelSerializer):
    colors = ColorSerializer(many=True, read_only=True)

    class Meta:
        model = Style
        fields = ['name', 'colors']

models.py

class Style(models.Model):
    name = models.CharField(max_length=36, unique=True)
    colors = models.ManyToManyField('Color', through='StyleColor')



class Color(models.Model):
    name = models.CharField(max_length=36, unique=True)



class Size(models.Model):
    name = models.CharField(max_length=12, unique=True)



class StyleColor(models.Model):
    style = models.ForeignKey('Style', on_delete=models.CASCADE)
    color = models.ForeignKey('Color', on_delete=models.CASCADE)
    sizes = models.ManyToManyField('Size', through='StyleColorSize')

    class Meta:
        unique_together = ('style', 'color')



class StyleColorSize(models.Model):
    style_color = models.ForeignKey('StyleColor', on_delete=models.CASCADE)
    size = models.ForeignKey('Size', on_delete=models.CASCADE)

    class Meta:
        unique_together = ('style_color', 'size')
like image 834
柳 Lau Avatar asked Jul 05 '18 03:07

柳 Lau


1 Answers

Thanks for all those who tried to answer. Got inspiration from the answer this link in case anyone gets into the same trouble as I did. Include intermediary (through model) in responses in Django Rest Framework.

class StyleSerializer(serializers.ModelSerializer):
    colors = StyleColorSerializer(source='stylecolor_set',
                                  many=True, read_only=True)

    class Meta:
        model = Style
        fields = ('name', 'colors')
like image 114
柳 Lau Avatar answered Oct 06 '22 01:10

柳 Lau