(工作小总结)Django REST Framework 性能优化,简单实现预加载功能

缘由: Django 的 ORM 是惰性的每个用户访问网站时候,都要进行一次数据交互


在最初开发的时候,需要考虑到用户量大的时候,
又由于 Django 的 ORM 是惰性的,它只取出当前查询所需响应最小的数据。它不知道你是否有成百上千的相同或相似的数据也需要取出来。因此访问网站时这势必会对数据库造成巨大压力!


有句话说的是:只要你在序列化中使用嵌套关系,你就在拿你的性能开玩笑那么怎么解决他呢?


解决的方法是用户访问时候进行预加载功能,即将数据提前加载到用户本地中。如何预加载呢?其实django已经提供了方法,在这里我将工作中常用的加载方式贴出来:

很简单!在你访问量大的视图添加:

queryset = queryset.prefetch_related('你的序列化器名')  

具体列子如下:

class CustomerSerializer(serializers.ModelSerializer):  
    orders = OrderSerializer(many=True, read_only=True)

    def setup_eager_loading(cls, queryset):
        """ Perform necessary eager loading of data. """
        queryset = queryset.prefetch_related('orders')
        return queryset

调用例子:

customer_qs = Customers.objects.all()  
customer_qs = CustomerSerializer.setup_eager_loading(customer_qs)  # Set up eager loading to avoid N+1 selects  
post_data = CustomerSerializer(customer_qs, many=True).data  

以上是简单实现预加载的原理,我想各位阅读预加载这块,代码经验应该还是有的吧??那我就直接贴出比较具体的代码块了,实现预加载功能!

  1. 首先创建一个简单的数据模型类:
from django.contrib.auth.models import User

class Event:  
    """ A single occasion that has many `attendees` from a number of organizations."""
    creator = models.ForeignKey(User)
    name = models.TextField()
    event_date = models.DateTimeField()

class Attendee:  
    """ A party-goer who (usually) represents an `organization`, who may attend many `events`."""
    events = models.ManyToManyField(Event, related_name='attendees')
    organization = models.ForeignKey(Organization, null=True)

class Organization:  
    name = models.TextField()

2.预加载代码如下:

class EventSerializer(serializers.ModelSerializer):  
    creator = serializers.StringRelatedField()
    attendees = AttendeeSerializer(many=True)
    unaffiliated_attendees = AttendeeSerializer(many=True)

    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        # select_related for "to-one" relationships
        queryset = queryset.select_related('creator')

        # prefetch_related for "to-many" relationships
        queryset = queryset.prefetch_related(
            'attendees',
            'attendees__organization')

        # Prefetch for subsets of relationships
        queryset = queryset.prefetch_related(
            Prefetch('unaffiliated_attendees', 
                queryset=Attendee.objects.filter(organization__isnull=True))
            )
        return queryset

总结:以上是django中实现预加载功能,总之:任何时候你通过 ORM 查询嵌套关系时,你都应该考虑建立适合的预加载。

猜你喜欢

转载自blog.csdn.net/lanxuezai/article/details/80910963
今日推荐