Django -senior

The article contains the senior knowledge of Django and Django REST framework…

Code in GitHub: django

用于优化SQL查询

Select_related用于处理一对一和多对一

Prefetch_related用于处理多对多和一对多

Select_related比prefetch_related效率要高

能用select_related就用它

Select_related和prefetch_related可以连用

要注意的是只有在prefetch_related之前的select_related有效,在它后面的会被直接无视

prefetch_related中的Prefetch

具体作用还没搞清楚,猜测是级联表的时候给某些表单独先做一些操作,比方说上面就是相当于先给contact_info表按照created_at倒序排列,再进行级联(但是这样好像没什么意义,也有可能是先级联,级联之后的表再按照contact_info的created_at倒序排列)

Values和values_list

Values()返回字典,多个字典用list包裹

其中可以传参选出特定的字段

Values_list()返回元组,多个元组用list包裹

与values()类似,也可以传参

当传参的个数只有一个的时候,可以使用flat=True去掉元组的括号

但是如果有多个字段,使用flat=True会报错

Values后面接annotate

上图写法表示按照投资者id和开放日id分组,并为每组计算ShareChanges中latest_share的总和

Aggregate

Sum

Total

和sum联用

Min

Max

Filter中的order_by

@action注解中的detail

Detail为False的话就直接是前缀/方法名

Detail为True的话会自动变成router登记前缀/{pk}/方法名

优化序列化器

优化的时候不想要序列化器中的method_field起作用,因为这些方法域会因为可能找不到该字段而进到数据库中查找,这会导致多次调用数据库,导致新能下降

那么怎么优化呢?

我们深入Django源码,发现调用序列化器所有的字段域的时候会有一个叫做self.fields的域,里面有所有即将被序列化的字段,其中包括了序列化器中的类方法域,那么如果想要跳过这些类方法域的序列化,其实只需要删除self.fields中相应的字段即可,我们可以通过传参来实现(注意这里必须写exclude_fields,到时候下面传参的时候也是写这个字段):

再来看看self.fields,其实就是Meta中的fields:

之后在调用序列化器的时候在后面加上参数表明想要删掉的字段:

一对多优化

https://www.jianshu.com/p/7a0ddbb02ae3

ContentType

GenericForeignKey

GenericRelation

优化使用(related_query_name)

系统自带的user

上图使用的django.contrib.auth.settings.AUTH_USER_MODEL是系统自带的user