一、自定义Manager
在后台接口开发过程中,对数据库进行ORM操作,其中查询是最复杂的,一般来说使用都是 XXX.objects.all() 获取models 对象的所有数据,但是实际开发过程中,业务逻辑更复杂,使用的SQL对应也是很复杂的,那么对应的ORM操作可能就会写的很复杂,如下图
当然,有的可能会比上面的demo要复杂很多倍,然后我每次有类似的查询的时候,不想再接口这里写这么多ORM查询操作,能不能把这个查询方法提取出来?作为一个公共的过滤器使用?
Django models 有内置的对象管理器 objects ,它可以获取所有的对象数据 objects = models.Mangger() ,它是由Django内置的 Manager 提供的查询及背后机制的支持。接下来可以自己自定义一个过滤类,如下:
get_queryset 是对象查询结果集,Manager 内置还有其他的方法,有兴趣的小伙伴可以自行去了解。
定义好一个过滤器之后,如何绑定到对应的 models 对象,看下图:
这里绑定自定义的管理之后,那么去 views.py 去试试是否可以实现以上自定义过滤的功能
注意:在同一模型上使用多个管理器。您可以根据需要将尽可能多的 Manager() 实例附加到模型
这样就可以把一些常用的查询提取出来,自定义管理器进行过滤,节省硬编码,当然这种方式不是必须的,根据自己实际业务和开发习惯来进行选择。不需要把所有的查询过滤都封装,那样就没意义了。
二、原生SQL查询
上面讲述的是 models 通过ORM操作内置的查询方式进行SQL操作,那如果在不熟悉ORM框架自带的方法,想直接使用原生SQL进行数据库操作呢?Django提供了两种执行原始SQL查询的方式:您可以 Manager.raw() 用来执行原生查询并返回模型实例,或者可以完全避开模型层直接执行自定义的SQL 。
1. 首先先来看看第一种:
当然,上述的demo很简单。但是,raw()还有很多其他选择,使其功能非常强大。有兴趣的小伙去可以自行去官网了解。
2. 现在看看第二种方式:
有时甚至 Manager.raw() 是不太够,可以直接执行查询 UPDATE,INSERT或DELETE查询。您始终可以直接访问数据库,并在整个模型层中进行路由。
django.db.connection:默认的数据库连接。
connection.cursor() : 以获取游标对象。
cursor.execute(sql, [params]) :执行SQL
cursor.fetchone():获取一个对象数据
cursor.fetchall():获取所有
注意:为防止SQL注入,需要在 %s 在SQL字符串中的占位符两边加上引号。如果要在查询中包括文字百分号,则在传递参数的情况下必须将它们加倍.
如果使用多个数据,则可以用于 django.db.connections 获取特定数据库的连接(和游标)。django.db.connections是一个类似于字典的对象,它允许您使用其别名检索特定的连接:
from django.db import connections
with connections['my_db_alias'].cursor() as cursor:
# Your code here...
默认情况下,Python DB API将返回不包含字段名称的结果,这意味着您最终得到的list是值,而不是dict。以较小的性能和内存成本。collections.namedtuple() 从Python标准库中使用。A namedtuple是一个类似元组的对象,具有可通过属性查找访问的字段;它也是可索引和可迭代的。结果是不可变的,可以通过字段名称或索引访问
from collections import namedtuple
def namedtuplefetchall(cursor):
"Return all rows from a cursor as a namedtuple"
desc = cursor.description
nt_result = namedtuple('Result', [col[0] for col in desc])
return [nt_result(*row) for row in cursor.fetchall()]
上述简单的分享了开发过程可能会用的数据库操作的过滤封装和原生SQL的执行方式,Django内置的方法还有很多,有兴趣的可以去官网了解
网友评论