Django Rest Framework Nested Serializers

这一生的挚爱 提交于 2020-08-25 07:45:31

问题


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')

回答1:


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')



回答2:


serializers.py

class ColorSerializer(serializers.ModelSerializer):

    class Meta:
        model = Color
        fields = '__all__'

class StyleSerializer(serializers.ModelSerializer):
    color = ColorSerializer() # each style has a set of colors attributed to it

    class Meta:
        model = Style
        fields = '__all__'

class SizeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Size
        fields = '__all__'

class StyleColorSerializer(serializers.ModelSerializer):
    size = SizeSerializer() # each style-color combination has a set of sizes attributed to it

    class Meta:
        model = StyleColor
        fields = '__all__'

Because your models are too complex, I'm afraid the code above didn't fit that well.

To be more general, if you wanna attach the queryset of B model at the same time when you fetch the queryset of A model (which has a relationship with B model), you have to define the BSerializer() in the class of ASerializer().



来源:https://stackoverflow.com/questions/51182823/django-rest-framework-nested-serializers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!