为 Viewset 优化 Django 数据库查询

问题描述 投票:0回答:0

我最近的任务是优化我们用 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 的调用。

python django django-rest-framework django-queryset
© www.soinside.com 2019 - 2024. All rights reserved.