Pythonpython 提升生活和办公效率

[Django]查询表达式

2021-05-02  本文已影响0人  alue

作为一个全栈开发工程师,我最喜欢Django框架中的ORM和Admin,很大程度上提升了开发效率。
其中,ORM虽然很好上手,但想要高效的操作数据库,还是需要很多经验的。善于使用查询表达式(Query Expressions)就是很重要的一个技能。
Django自带的查询表达式有

# 1. F() 能够在数据库层面操作,减少读入内存的损耗
from django.db.models import F

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()


# 2. Func() 能够使用数据库函数
queryset.annotate(field_lower=Func(F('field'), function='LOWER'))

# 3. Aggregate()是一些聚合函数的基础,标志着查询带有GROUP BY语句,例如Count(),Max()
Aggregate()

# 4. 最小表达单元. 将python数据转换为数据库表达式。当书写F('field') + 1时,Django会自动将1改为Value(1)
Value()
# 5. ExpressionWrapper()用于表达式的嵌套;下面是一个实战案例,加权求和的高效算法
queryset.annotate(
            hours_x_number=ExpressionWrapper(
                F("hours") * F("number"),
                output_field=FloatField()
            )
        ).aggregate(
            total_hours_x_number=Sum('hours_x_number')
        )["total_hours_x_number"]

# 6. Subquery()提供一种更清晰的表达式
newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))

提供一个Value()表达式在实战中的应用

打算将模型两个字段拼接成一个并输出,拼接规则是(字段1)字段2,即字段1需要先用括号括起来。

常规的做法,先将数据库字段读到内存中,然后再用Python拼接,这样耗时较长。
进阶的做法是利用查询表达式Value():

queryset.annotate(
                combined_fields=Concat(
                    Value(' ('),
                    'field1',
                    Value(')'),
                    "field2",
                    output_field=CharField()
                )).

这样,操作直接在数据库层面完成,效率大增。

计算一个模型中两个字段乘积的总和

常规做法,利用for循环,在python内存中累加。
进阶做法,利用ExpressionWrapper和F,在数据库中完成.

queryset.annotate(
            hours_x_number=ExpressionWrapper(
                F("hours") * F("number"),
                output_field=FloatField()
            )
        ).aggregate(
            total_hours_x_number=Sum('hours_x_number')
        )["total_hours_x_number"]
上一篇下一篇

猜你喜欢

热点阅读