Django REST框架一对多关系和数据库查询



我是django的新手,我正在用django REST框架开发我的第一个项目。

型号:

class Sticker(Model):
image = models.ImageField(upload_to=sticker_image_directory_path, null=False)
title = models.CharField(max_length=150)
def __str__(self):
return self.title
class StickerTag(Model):
name = models.CharField(max_length=100)
sticker = models.ForeignKey(Sticker, on_delete=models.RESTRICT, related_name='tags')
def __str__(self):
return self.name

序列化程序:

class StickerSerializer(serializers.ModelSerializer):
tags = serializers.StringRelatedField(many=True)

class Meta:
model = models.Sticker
fields = ['id', 'image', 'title', 'tags', 'countries']

视图:

class StickerView(mixins.ListModelMixin,
viewsets.GenericViewSet):
serializer_class = serializers.StickerSerializer
queryset = models.Sticker.objects.all()

我正在用django-debug-toolbar调试对http://127.0.0.1:8000/stickers/的调用。我惊讶地发现,对于每个标签实例,Django都会对粘贴标签表进行如下查询:

SELECT `stickerapp_stickertag`.`id`,
`stickerapp_stickertag`.`name`,
`stickerapp_stickertag`.`sticker_id`
FROM `stickerapp_stickertag`
WHERE `stickerapp_stickertag`.`sticker_id` = 1

意味着它正在为每个贴纸逐一抓取贴纸标签。因此,如果有10个贴纸,它将使用上面的查询进行10个DB调用。但我认为这些查询太多了,可以通过使用";IN";MYSQL的子句,例如:

SELECT * FROM stickerapp_stickertag where sticker_id in (1,2,3,4,5);

我不知道如何在Django REST框架中做到这一点。请引导!

您可以.prefetch_related(…)[Django-doc]相关的Tag对象:

class StickerView(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = serializers.StickerSerializer
queryset = models.Sticker.objects.prefetch_related('tags')

这将进行两个查询,第一个查询用于获取所有Sticker对象,第二个查询用于为每个Sticker获取相关标签。这是在所有Stickers的单个查询中完成的。

最新更新