Django中的嵌套外键序列化器不起作用

时间:2018-08-23 15:45:02

标签: python django django-rest-framework django-serializer

models.py的一部分:

class FoodCuisine(models.Model):
    cuisine = models.CharField(max_length=64)

    def __str__(self):
        return self.cuisine


class CuisineTypes(models.Model):
    cuisine_types = models.CharField(max_length=64)
    cuisine = models.ForeignKey(FoodCuisine, on_delete=models.CASCADE)

    def __str__(self):
        return self.cuisine_types

    class Meta:
        ordering = ('cuisine_types',)


class Food(models.Model):
    name = models.CharField(max_length=192)
    veg = models.BooleanField(default=0)
    cuisine_type = models.ForeignKey(CuisineTypes, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    def _cuisine(self):
        return self.cuisine_type.cuisine

serializers.py

class FoodSerializer(serializers.ModelSerializer):
    class Meta:
        model = Food
        fields = ('name', 'veg')


class CuisineTypesSerializer(serializers.ModelSerializer):
    foods = FoodSerializer(many=True, read_only=True, source='food_set')
    class Meta:
        model = CuisineTypes
        fields = ('cuisine_types', 'foods')


class FoodCuisineSerializer(serializers.ModelSerializer):
    cuisine_type = CuisineTypesSerializer(many=True, read_only=True, source='cuisinetypes_set')
    class Meta:
        model = FoodCuisine
        fields = ('cuisine', 'cuisine_type')

我希望FoodCuisineSerializer返回一个嵌套列表,该列表将按照其各自的美食类型和美食对所有食物进行分类。

分类很简单,第一层是美食列表,第二层是美食类型,第三层是美食。

问题是FoodCuisineSerializer仅返回第一级,仅显示美食列表。但是我想要上一段完整的嵌套食物列表。

编辑1:

https://pastebin.com/dmVbyS0G是我从Django shell获得的。

编辑2:

如果我写

>>> y = FoodCuisineSerializer(FoodCuisine.objects.get(id=2))
>>> y.cuisine_type
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'FoodCuisineSerializer' object has no attribute 'cuisine_type'

为什么会出现上述错误?

编辑3:

source放在正确的位置,但现在我得到了:

>>> y = FoodCuisineSerializer(FoodCuisine.objects.get(id=2))
>>> y.data # I get the desired result having OrderedDict
>>> y = FoodCuisineSerializer(FoodCuisine.objects.all())
>>> y.data
[Error]

[错误]:https://pastebin.com/0DW28qv4接下来是什么?

1 个答案:

答案 0 :(得分:1)

在将查询集序列化为时,设置 source='cuisinetypes_set'

class FoodCuisineSerializer(serializers.ModelSerializer):
    cuisine_type = CuisineTypesSerializer(many=True, read_only=True, source='cuisinetypes_set')

    class Meta:
        model = FoodCuisine
        fields = ('cuisine', 'cuisine_type')


参考
1. reverse relationship
2. source in DRF-Serializer


更新1
由于FoodCuisine.objects.all()QuerySetlist类型的对象),因此您应该在序列化程序中传递 many=True ,就像

y = FoodCuisineSerializer(FoodCuisine.objects.all(), many=True)