Django小技巧16: 数据库访问优化

Django小技巧16: 数据库访问优化

Posted November 05, 2018

#错综复杂

翻译整理自: simpleisbetterthancomplex.com

本篇分享数据库访问优化相关, 读完这些并不是让你立即去优化代码, 更多的时候对于现有代码的优化, 需要借助Django Debug Toolbar来分析后, 再去相应的优化代码, 但今天要说的是一些简单的技巧, 用于你在编写代码的时候就所有规避不好用法, 使用推荐的用法.

访问外键值

如果你只需外键的ID

Python

Do

post.author_id

Python

Don't

post.author.id

如果你的博文中有一个 author 的外键,Django 会自动将主键存储在属性author_id中, 而在author属性则是一个惰性的数据库引用。如果你如果使用author来访问 ID, 数据则会多出一个额外的查询,就会产生开销。

批量插入Many to Many字段

Python

Do

user.groups.add(administrators, managers)

Python

Don't

user.groups.add(administrators)
user.groups.add(managers)

Count QuerySets

如果你只需获取 QuerySet count

Python

Do

users = User.objects.all()
users.count()

# Or in template...
{{ users.count }}

Python

Don't

users = User.objects.all()
len(users)

# Or in template...
{{ users|length }}

Empty QuerySets

如果你只想知道 QuerySets 是否为空.

Python

Do

groups = Group.objects.all()
if groups.exists():
    # Do something...

Python

Don't

groups = Group.objects.all()
if groups:
    # Do something...

减少不必要的查询次数

就是之前讲过的 select_related

Python

Do

review = Review.objects.select_related('author').first()  # Select the Review and the Author in a single query
name = review.author.first_name

Python

Don't

review = Review.objects.first()  # Select the Review
name = review.author.first_name  # Additional query to select the Author

只检索需要的字段

假设模型Invoice有50个字段,你想要创建一个表格只显示摘要信息,包含numberdatevalue.

Python

Do

# views.py
# If you don't need the model instance, go for:
invoices = Invoice.objects.values('number', 'date', 'value')  # Returns a dict

# If you still need to access some instance methods, go for:
invoices = Invoice.objects.only('number', 'date', 'value')  # Returns a queryset

# invoices.html
<table>
  {% for invoice in invoices %}
    <tr>
      <td>{{ invoice.number }}</td>
      <td>{{ invoice.date }}</td>
      <td>{{ invoice.value }}</td>
    </tr>
  {% endfor %}
</table>

Python

Don't

# views.py
invoices = Invoice.objects.all()

# invoices.html
<table>
  {% for invoice in invoices %}
    <tr>
      <td>{{ invoice.number }}</td>
      <td>{{ invoice.date }}</td>
      <td>{{ invoice.value }}</td>
    </tr>
  {% endfor %}
</table>

批量更新

使用 F() 批量更新.

Python

Do

from django.db.models import F

Product.objects.update(price=F('price') * 1.2)

Python

Don't

products = Product.objects.all()
for product in products:
    product.price *= 1.2
    product.save()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT技术精选文摘

JVM致命错误日志(hs_err_pid.log)分析

当jvm出现致命错误时,会生成一个错误文件 hs_err_pid<pid>.log,其中包括了导致jvm crash的重要信息,可以通过分析该文件定位到导致cr...

6255
来自专栏用户2442861的专栏

Epoll详解及源码分析

对于水平触发模式(LT):在1处,如果你不做任何操作,内核依旧会不断的通知进程文件描述符准备就绪。

1212
来自专栏阮一峰的网络日志

Systemd 定时器教程

Systemd 作为 Linux 的系统启动器,功能强大。 本文通过一个简单例子,介绍 Systemd 如何设置定时任务。这不仅实用,而且可以作为 System...

3164
来自专栏Golang语言社区

几种服务器端IO模型的简单介绍及实现(下)

5、使用事件驱动库libevent的服务器模型 Libevent 是一种高性能事件循环/事件驱动库。 为了实际处理每个请求,libevent 库提供一种事件机制...

3769
来自专栏星流全栈

Meteor React Native 项目模板更新啦!

1273
来自专栏linux驱动个人学习

cyclictest 简介

1. cyclictest 简介以及安装 1.1 cyclictest 简介       cyclictest 是什么? 看名字应该就能大致猜出来它是一种 te...

5714
来自专栏Golang语言社区

几种服务器端IO模型的简单介绍及实现(下)

5、使用事件驱动库libevent的服务器模型 Libevent 是一种高性能事件循环/事件驱动库。 为了实际处理每个请求,libevent 库提供一种事件机制...

2927
来自专栏逸鹏说道

REDIS操作命令小结

缘由: 最初学过一段时间的Redis的使用,但是后来长时间没有接触,就又忘了,往复这么弄了几次,感觉比较浪费时间,所以今天决定整理一下Redis的常见操作命令,...

3585
来自专栏java初学

memcached

2996
来自专栏xingoo, 一个梦想做发明家的程序员

Elasticsearch 数据搜索篇·【入门级干货】

ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API。本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用。虽然不能让你理解ES的原...

2717

扫码关注云+社区

领取腾讯云代金券