Django Manager属性

Django Manager属性,Manager是Django模型最重要的属性,通过使用Manager模型才可以操作数据库。默认情况下,Django会为每一个模型提供一个名为objects的Manager实例。Manager属性只能通过模型类访问。

自定义Manager类

默认情况下可以使用Model.objects所提供的方法操作数据库,也可以实现自定义Manager类:

from django.db import models
class Person(models.Model):
    #...
    people = models.Manager()

此时查找数据的方式如下:

Person.people.all()

直接执行SQL语句

虽然Manager类非常强大,但是有些情况下我们仍然希望自己手写SQL语句。对此Django提供了以下两种方法允许开发人员直接执行SQL语句。

  1. 使用Manager.raw()方法
    Manager.raw()方法可以用来执行一段SQL语句并返回Django模型实例。
    语法:
Manager.raw(raw_query, params=None, translations=None)

raw()方法返回一个django.db.models.query.RawQuerySet实例,RawQuerySet与前面的QuerySet一样可以被循环遍历。

下图是一个在Shell中使用raw()方法查看全部博客文章的例子。
Django Manager属性

虽然Django允许用户在raw()方法中执行任意SQL语句,但是Django希望SQL语句能够返回一行或多行数据,如果执行结束没有返回任何数据,raw()方法将会抛出异常。

Manager.raw()方法能够自动将查询结果转换为对应的模型,即使在查询语句中使用了AS关键字对字段名进行了修改也没关系,只要数据库中的字段名与模型字段匹配成功即可,如图所示。
Django Manager属性

Manager.raw()方法所执行的SQL语句中除了可以包含模型字段外,还可以包含其他聚合函数值,如在查找全部博客文章时顺便输出文章名字所包含的字符数(length是MySQL函数),如图所示。
Django Manager属性

Manager.raw()方法还可以对SQL语句进行参数化,参数可以是列表或者字典,如图(a)或图(b)所示。
Django Manager属性

  1. 脱离模型,直接执行SQL
    由于Manager.raw()的执行结果总是对应一个模型,而真正软件产品中不只是查询单个模型,还会有更复杂的情况,例如执行更新、删除、插入等操作。因此我们需要跳出模型系统而直接执行SQL语句。

django.db.connection对象提供了数据库连接操作,使用connection.cursor()方法可以得到一个游标对象,cursor.execute(sql, [params])方法用于执行指定的SQL语句。使用cursor. fetchone()或者cursor.fetchall()方法可以得到一个或全部结果。
示例:

from django.db import connnection

def my_custom_sql(self):
    with connection.cursor() as cursor:
        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
        cursor.execute("SELECT foo FROM bar WHERE baz = %s")

如果当前工程包含多个数据库,可以使用django.db.connections对象获取数据库连接,例如连接数据库polls可以使用connections['polls']

需要注意的是,cursor所返回的数据只是数据库中所有字段的值,也就是一个数值的列表,而不是一个同时包含字段名与字段值的字典,为了使返回的数据更方便使用,可以使用下面方法将返回结果转换为字典:

def dictfetchall(cursor):
    "Return all rows from a cursor as a dict"
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
    ]

在Shell中重新执行查询操作,如图所示。
Django Manager属性

  1. 执行存储过程
    语法:
CursorWrapper.callproc(procname, params=None, kparams=None)

注意,只有Oracle支持kparams参数。
示例:

with connection.cursor() as cursor:
        cursor.callproc('test_procedure', [1, 'test'])

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!