我最近的任务是优化我们用 drf 编写的一些 django rest api 的数据库查询和性能,并且能够成功地使用
prefetch_related()
来实现它们。
但是有一个用例我一直无法解决并正在寻求支持。
结构如下:
Models.py
class Section(models.Model):
section_tags = models.ManyToManyField(AssetTag)
section_name = models.CharField(max_length=200)
section_createdate = models.DateTimeField(auto_now=True)
class Collection(models.Model):
section = models.ForeignKey(Section, on_delete=models.CASCADE, related_name="collection_set")
system_tags = models.ManyToManyField(AssetTag, blank=False, related_name='system_tags_poster_collections')
card = models.ManyToManyField(Card)
class Card(models.Model):
tag = models.ManyToManyField(CardTag) # should we deprecate?
system_tags = models.ManyToManyField(AssetTag, blank=False, related_name='system_tags_poster_cards')
card_name = models.CharField(max_length=200)
views.py
class SectionViewset(viewsets.ModelViewSet):
serializer_class = serializers.SectionSerializer
http_method_names = ['get']
def get_queryset(self):
queryset = Section.objects.filter(section_status=True, section_expiredate__gte=datetime.now())
return queryset
serializer.py
class SectionSerializer(serializers.ModelSerializer):
collection_set = CollectionSerializer(many=True, read_only=True)
class FilteredCollectionSerializer(serializers.ListSerializer):
def to_representation(self, data):
data = data.filter(collection_status=True, collection_expiredate__gte=datetime.now())
return super(FilteredCollectionSerializer, self).to_representation(data)
class CollectionSerializer(serializers.ModelSerializer):
card = CardSerializer(many=True, read_only=True)
system_tags = AssetTagBadgeSerializer(many=True, read_only=True)
class Meta:
list_serializer_class = FilteredCollectionSerializer
model = Collection
fields = ('id', 'card', 'system_tags')
class CardSerializer(serializers.ModelSerializer):
tag = CardTagSerializer(many=True, read_only=True)
system_tags = AssetTagBadgeSerializer(many=True, read_only=True)
# method_name = 'get_template_id'
class Meta:
model = Card
fields = ('id', 'card_name', 'card_image', 'card_createdate', 'tag', 'system_tags')
class AssetTagBadgeSerializer(serializers.ModelSerializer):
class Meta:
model = AssetTag
fields = ('id', 'tag_name')
我无法应用 prefetch_related() 来优化 SectionViewSet 上的查询,因为它在集合模型中是一种反向关系。有什么方法可以优化对 db 的调用,因为我在应用程序性能监控系统中看到很多对 card__tag 和 card__system_tags 的调用。