天天看点

你不知道的django orm(orm 优化)你不知道的django orm

你不知道的django orm

orm优化小知识

模型:

from django.db import models


class User(models.Model):
    username = models.CharField(max_length=100, verbose_name="用户名")
    password = models.CharField(max_length=255, verbose_name="密码")
    age = models.SmallIntegerField(verbose_name="年龄")
    birth = models.DateField(auto_now_add=True, verbose_name="出生日期")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
           

当我们使用django更新数据通常会使用两种方式

# 方式一:
user = User.objects.get(pk=1)
user.username = "zhenyu"
user.save()
# 方式二:
n = User.objects.filter(pk=1).update(username="zhenyu")  # 返回影响的行数
           

这两种方式的区别

方式一会发生两次sql查询

方式二只会发生一次sql查询

方式一还可以优化。

我们来看看当方式一中调用.save()方法后会执行怎么样的sql语句

(0.001) UPDATE "app01_user" SET "username" = 'zhenyu', "password" = '2', "age" = 18, "birth" = '2021-09-14', "created_time" = '2021-09-14 12:41:42.247603', "updated_time" = '2021-09-14 13:02:22.900226' WHERE "app01_user"."id" = 1; args=('zhenyu', '2', 18, '2021-09-14', '2021-09-14 12:41:42.247603', '2021-09-14 13:02:22.900226', 1)
[14/Sep/2021 13:02:22] "GET /demo/ HTTP/1.1" 200 7
           

可以看到我只修改了一个字段,但是djano orm却把模型的所有字段值都给带上了。这样肯定会影响性能。可以想象修改一个值和修改多个值所花费的时间肯定是不一样的。

优化的技巧:

user = User.objects.get(pk=1)
user.username = "zhenyu"
user.save(update_fields=["username"])
           

明确要修改的字段写到update_fields列表中。这样我们再来看看会发生怎样的sql语句

(0.000) UPDATE "app01_user" SET "username" = 'zhenyu' WHERE "app01_user"."id" = 1; args=('zhenyu', 1)
[14/Sep/2021 13:06:35] "GET /demo/ HTTP/1.1" 200 7
           

可以看到,只会修改我要修改的字段,不会把不修改的字段值也带上。

这里还有一个小细节

我们的模型中是有一个更新字段的。这个更新字段是django orm帮我们自动更新的。调用.save()方法也需要明确写到update_fields,不然不会更新。

user = models.User.objects.get(pk=1)
user.username = "zhenyu"
user.save(update_fields=["username", "updated_time"])

           

这样django orm才会帮我们更新时间字段。