python - Django REST framework 一对多关系和数据库查询
问题描述
我是 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()
我正在调试对http://127.0.0.1:8000/stickers/
with 的调用django-debug-toolbar
。我很惊讶地看到,对于每个贴纸实例,Django 都会像这样对贴纸标签表进行查询:
SELECT `stickerapp_stickertag`.`id`,
`stickerapp_stickertag`.`name`,
`stickerapp_stickertag`.`sticker_id`
FROM `stickerapp_stickertag`
WHERE `stickerapp_stickertag`.`sticker_id` = 1
意味着它正在为每个贴纸一张一张地抓取贴纸标签。因此,如果有 10 个贴纸,它将使用上述查询进行 10 次 DB 调用。但我认为这些查询太多了,可以通过使用 MYSQL 的“IN”子句来减少,例如:
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
获取相关标签。这是在对所有 Sticker
s的单个查询中完成的。
推荐阅读
- google-app-engine - 如何使部署到谷歌云应用引擎的应用程序可用于某些白名单 IP
- java - 将类的实例添加到 Arraylist
- mysql - 用 Where 删除。程序会删除所有内容。为什么?
- java - 如何知道自定义 Java 节点是否包含在第二个节点中?
- android - 在 Android 上监听连接变化
- python - 如何在 Keras 中格式化 ImageDataGenerator 的 X 和 Y 数据?
- python - Can't install gcloud on Amazon Linux : invalid syntax
- swift - 如何替换字符串中出现的有限次数
- sql - 对 ODBC 表使用多个左连接的查询失败
- python - Pyspark 用 NULL 替换 NaN