0、数据库配置

django默认支持sqlite,mysql, oracle,postgresql数据库。Django连接数据库默认编码使用UTF8,使用中文不需要特别设置。

sqlite
django默认使用sqlite的数据库,默认自带sqlite的数据库驱
引擎名称:django.db.backends.sqlite3
mysql
引擎名称:django.db.backends.mysql

mysql引擎配置:

'defaults': {
  'ENGINE': 'django.db.backends.mysql',
  'NAME':'127.0.0.1',
  'USER':'root',
  'PASSWORD':'',
  }

mysql引擎底层驱动的py3支持问题:

mysql驱动程序
MySQLdb(mysql python),Django默认使用改驱动,但改驱动在python3下存在兼容性问题。因此使用PyMySQL。
PyMySQL(纯python的mysql驱动程序)
mysql驱动python3解决方法
找到项目名文件下的__init__,在里面写入:
import pymysql
pymysql.install_as_MySQLdb()

一、Model类定义

1、Model类创建

下面这个模型类将作为本篇博客的基础模型,所有的实例都基于此。

from django.db import models

class Publisher(models.Model):
name = models.CharField(max_length=30, verbose_name="名称")
website = models.URLField()
# book_set 反向关联一对多字段的Book
def __unicode__(self):
return self.name class Author(models.Model):
name = models.CharField(max_length=30)
# authordetail 反向关联一对一字段AuthorDetail表
# book_set 反向关联一对多字段的Book
def __unicode__(self):
return self.name
class AuthorDetail(models.Model):
sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))
author = models.OneToOneField(Author)
# author_id隐藏字段,正向关联一对一字段的Author对象的id class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher,null=True)
# publisher_id隐藏字段,正向关联一对多字段的Publisher对象的id
price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
def __unicode__(self):
return self.title
#coding:utf-
from __future__ import unicode_literals from django.db import models class Publisher(models.Model):
name = models.CharField(max_length=, verbose_name="名称")
website = models.URLField()
def __unicode__(self):
return self.name class Author(models.Model):
name = models.CharField(max_length=)
def __unicode__(self):
return self.name class AuthorDetail(models.Model):
sex = models.BooleanField(max_length=, choices=((, '男'),(, '女'),))
author = models.OneToOneField(Author) class Book(models.Model):
title = models.CharField(max_length=)
authors = models.ManyToManyField(Author,through='Book2Author')
publisher = models.ForeignKey(Publisher)
price=models.DecimalField(max_digits=,decimal_places=,default=)
def __unicode__(self):
return self.title class Book2Author(models.Model):
book = models.ForeignKey(Book)
author = models.ForeignKey(Author)
groupname = models.CharField(max_length=) #默认多对多关系Django自动为我们创建了一张中间表,仅提供3个字段,两个关联表的外键字段和一个id字段。
#这种使用自定义中间表的方式,使得我们可以自定义的为中间表添加额外的字段。当我们需要为多对多关系提供额外字段时,用此方式。

自定义多对多中间表

2、同步数据库

模型表创建和更新的时候是要使用数据库迁移命令,使模型类的改变同步到数据库。

makemigrations    #创建变更记录
migrate #同步到数据库

3、Model类(表)关系图:

名词说明:

  正向查询,从定义关系字段的类中去查询关系对象的值或值的集合。举个栗子:从AuthorDetail类中查询关联字段author对象的值。

  反向查询,从本类中查询被关联对象中的值或值的集合。举个栗子:从Author对象中查询被关联字段AuthorDetail对象的值。

4、字段类型:

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制
23、models.ImageField 图片
24、models.FilePathField 文件

ORM字段类型

5、字段选项:

1、null=True
  数据库中字段是否可以为空
2、blank=True
  django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
  auto_now 自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add 自动创建---永远是创建时的时间
5、choices 配置可选项
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length 最大长度
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column  数据库中的字段名称
10、unique=True  不允许重复
11、db_index = True  数据库索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[] 自定义数据格式验证
17、upload-to 上传文件路径

字段选项

6、Model类的Meta(元数据)选项:

abstract=False     True就表示模型是抽象基类
db_table = 'music_album' 自定义数库的表名称前缀
get_latest_by = "datefield_name" 根据时间字段datefield_name排序,latest()和earliest()方法中使用的默认字段。
db_tablespace 当前模型所使用的数据库表空间的名字。默认值是项目设置中的DEFAULT_TABLESPACE。如果后端并不支持表空间,这个选项可以忽略。
ordering = ['-fieldname'] 对象默认的顺序,字段前面带有'-'符号表示逆序,否则正序。排序会增加查询额外开销。
proxy = True 它作为另一个模型的子类,将会作为一个代理模型。
unique_together 设置联合唯一。ManyToManyField不能包含在unique_together中。
index_together 设置联合索引。
index_together = [
["pub_date", "deadline"],
]
方便起见,处理单一字段的集合时index_together = ["pub_date", "deadline"] verbose_name 在Admin里,个易于理解的表名称,为单数:verbose_name = "pizza"
verbose_name_plural 在Admin里显示的表名称,为复数:verbose_name_plural = "stories",一般同verbose_name一同设置。

Meta元数据选项

二、对象CURD操作

2.1 基础对象CURD(无关联字段)

1、增

方法一:
author= Author(name="鲁迅")
author.save() 方法二
创建对象并同时保存对象的快捷方法,存在关系字段时无法用此方法创建。
create(**kwargs)
Author.objects.create(name=u"鲁迅") 方法三:
批量创建
bulk_create(objs, batch_size=None) ret=Blog.objects.bulk_create([ Author(name="徐志摩"), Author(name="李白")]) 方法四:
存在就获取,不存在就创建
get_or_create(defaults=None,**kwargs),
defaults必须为一个字典,在创建时生效的默认值;**kwargs为查询条件。
创建对象时,使用**kwargs和defaults共同作用,取交集,defaults优先。 updated_values={"name":u"美猴王"}
a、存在就获取,查询到结果多余一个出错MultipleObjectsReturned
ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)
ret:(<Author: 徐志摩>, False)
b、不存在就创建
ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)
ret:(<Author: 美猴王>, True) 方法五:
存在就更新,不存在就创建
update_or_create(defaults=None, **kwargs)
a、存在就更新
updated_values={"name":u"猴王"}
ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子")
ret:(<Author: 猴王>, False)
根据给出的查询条件name=u"猴子"查找对象,查询到结果就使用defaults字典去更新对象。 b、不存在就创建
ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子1")
ret:(<Author: 猴王>, True)
defaults必须为一个字典,在创建时生效的默认值;**kwargs为查询条件。
创建对象时,使用**kwargs和defaults共同作用,取交集,defaults优先。
2、删
使用delete会查找出相关表中的有关联的数据行一并删除
方法一
Author.objects.filter(name="徐志摩").delete()
(1, {u'otest.Book_authors': 0, u'otest.AuthorDetail': 0, u'otest.Author': 1})
方法二:
a9=Author.objects.get(name="鲁迅")
a9.delete()
3、改
方法一:
update(**kwargs)返回更新的行数,批量修改
ret=Author.objects.filter(name='秋雨').update(name="陶渊明") 方法二:
单条修改
a7=Author.objects.get(name="清风")
a7.name=u"宋清风"
a7.save()
4、查
a、查询结果非QuertSet
get(**kwargs)
在使用 get() 时,如果符合筛选条件的对象超过一个,就会抛出 MultipleObjectsReturned 异常。
在使用 get() 时,如果没有找到符合筛选条件的对象,就会抛出 DoesNotExist 异常。
from django.core.exceptions import ObjectDoesNotExist
try:
e = Entry.objects.get(id=3)
b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
print("Either the entry or blog doesn't exist.") in_bulk(id_list)
接收一个主键值列表,然后根据每个主键值所其对应的对象,返回一个主键值与对象的映射字典。
Author.objects.in_bulk([1,2,3])
{1: <Author: 苍松>, 2: <Author: 猴王>, 3: <Author: 宋清风>} first() 查询第一条,一般使用前先排序,或者确定其只有一条数据。
last() 查询最后一条,同上 count() 返回数据库中匹配查询(QuerySet)的对象数量。 count() 不会抛出任何异常。 exists() 如果 QuerySet 包含有数据,就返回 True 否则就返回 False。这可能是最快最简单的查询方法了。 latest(field_name=None) ,根据时间字段 field_name 得到最新的对象。
earliest(field_name=None), 根据时间字段 field_name 得到最老的对象。
#F使用查询条件的值,进行数值计算

from django.db.models import F
Book.objects.filter(id=1).update(price=F('price')+10)

b、查询结果为QuerySet

 常用方法:

1、filter(**kwargs)
过滤,返回一个新的QuerySet,包含与给定的查询参数匹配的对象。
>>>q=Author.objects.filter(name=u"苍松")
>>> q
[<Author: 苍松>] 2、exclude(**kwargs)
反过滤,返回一个新的QuerySet,它包含不满足给定的查找参数的对象。功能与filter相反。 3、values(*fields)
返回一个新的QuerySet,但迭代时返回字典而不是模型实例对象。
*fields表示需要取哪些字段,空表示取所有字段。
>>> q=Author.objects.values("id")
>>> q
[{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 18}, {'id': 22}, {'id': 24}] 4、values_list(*fields, flat=False)
返回一个新的QuerySet,但迭代时返回元组而不是模型实例对象。
*fields表示需要取哪些字段,空表示取所有字段。flat=True表示返回的结果为单个值而不是元组,多个字段时不能使用flat。
>>> q=Author.objects.values_list("id")
>>> q
[(1,), (2,), (3,), (4,), (18,), (22,), (24,)]
>>> q=Author.objects.values_list("id",flat=True)
>>> q
[1, 2, 3, 4, 18, 22, 24] 5、all()
返回当前 QuerySet所有对象。 6、select_related(*field)
返回一个QuerySet,使用JOIN语句连表查询。它会在执行查询时自动跟踪外键关系,一次读取所有外键关联的字段,并尽可能地深入遍历外键连接,以减少数据库的查询。但数据关系链复杂的查询需要慎用。仅对外键生效。 7、prefetch_related(*field)
prefetch_related()的解决方法是,分别查询每个表,然后用Python处理他们之间的关系。外键和多对多都生效。 8、order_by(*fields)
排序,返回一个新的QuerySet,隐式的是升序排序,-name表示根据name降序
>>> q=Author.objects.order_by("name")
>>> q
[<Author: au>, <Author: 宋清风>, <Author: 猴王>, <Author: 美猴王>, <Author: 苍松>, <Author: 赵清风>, <Author: 陶渊明>]
>>> q=Author.objects.order_by("-name")
>>> q
[<Author: 陶渊明>, <Author: 赵清风>, <Author: 苍松>, <Author: 美猴王>, <Author: 猴王>, <Author: 宋清风>, <Author: au>] 9、reverse()
reverse()方法返回反向排序的QuerySet。
必须对一个已经排序过的queryset(也就是q.ordered=True)执行reverse()才有效果。 10、distinct([*fields])
去重复。返回一个在SQL 查询中使用SELECT DISTINCT 的新QuerySet。
1、dates(field, kind, order='ASC')
field 是你的 model 中的 DateField 字段名称。
kind 是 “year”, “month” 或 “day” 之一。 每个 datetime.date对象都会根据所给的 type 进行截减。
“year” 返回所有时间值中非重复的年分列表。
“month” 返回所有时间值中非重复的年/月列表。
“day” 返回所有时间值中非重复的年/月/日列表。
order, 默认是 ‘ASC’,只有两个取值 ‘ASC’ 或 ‘DESC’。它决定结果如何排序。 2、datetimes(field, kind, order=’ASC’)
返回一个 DateTimeQuerySet,参数与dates类似,多了"hour", "minute" ,"second" 3、none()
返回一个 EmptyQuerySet,它是一个运行时只返回空列表的 QuerySet。它经常用在这种场合:你要返回一个空列表,但是调用者却需要接收一个 QuerySet 对象。 4、defer(*fields)
将不想载入的字段的名称传给 defer() 方法,就可以做到延后载入。
在某些数据复杂的环境下,你的 model 可能包含非常多的字段,可能某些字段包含非常多的数据(比如,文档字段),或者将其转化为Python对象会消耗非常多的资源。在这种情况下,有时你可能并不需要这种字段的信息,那么你可以让 Django 不读取它们的数据。 5、only(*fields)
only() 方法或多或少与 defer() 的作用相反。如果你在提取数据时希望某个字段不应该被延后载入,而应该立即载入,那么你就可以做使用 only()方法。 6、多数据库切换using(alias)
单独使用无意义,配合其他查询集方法一起使用。
Author.objects.using('backup') 7、表锁定select_for_update(nowait=False)
单独使用无意义,配合其他查询集方法一起使用。
返回queryset,并将需要更新的行锁定,类似于SELECT … FOR UPDATE的操作。
entries = Entry.objects.select_for_update().filter(author=request.user)
所有匹配的entries都会被锁定直到此次事务结束。

其他方法

特别的:QuerySet可以使用切片限制查询集。
切片后依旧获得QuerySet,并且不会触发数据库查询。
>>> a=Author.objects.all()[0:2]
>>> type(a)
<class 'django.db.models.query.QuerySet'> 设置步长值后,获得到List类型值。触发数据库查询
>>> a=Author.objects.all()[::2]
>>> type(a)
<type 'list'> 使用索引,数据对象,触发数据库查询
>>> Author.objects.all()[0]  #等价于Author.objects.all()[0:1].get()
<Author: 苍松>
查看QuerySet的原始SQL语句
关于查看QuerySet的原始SQL语句,使用查询集的query对象。
>>> q=Author.objects.all()
>>> print q.query
SELECT "otest_author"."id", "otest_author"."name" FROM "otest_author"

 c、查询条件(双下划线)

所有使用查询条件的查询和查询集过滤的方法(get,get_or_create,filter,exclude等)都可以使用双下划线组合出更复杂的查询条件。

另一种使用双下划线的情况就是跨表条件查询单情况,见下一节关联字段中跨表查询。

查询条件格式
field__条件类型,例如a=Author.objects.get(id__exact=1)
默认为精确匹配
例如:Author.objects.get(id=1)等价于Author.objects.get(id__exact=1) 一、精确匹配
exact 精确匹配: Blog.objects.get(id__exact=1)
iexact 忽略大小写的精确匹配,Blog.objects.filter(name__iexact='blog7')
二、模糊匹配
(模糊匹配,仅PostgreSQL 和 MySQL支持. SQLite的LIKE 语句不支持大小写敏感特性,因此模糊匹配对于 SQLite无法对大敏感)
contains 大小写敏感的内容包含测试:Blog.objects.filter(name__contains='blog7')
icontains 大小写不敏感的内容包含测试:
startswith 大小写敏感的内容开头 Blog.objects.filter(name__startswith="blog")
endswith 大小写敏感的内容结尾 endswith.
istartswith 大小写不敏感的内容开头 startswith.
iendswith 大小写不敏感的内容结尾 endswith. 三、正则匹配
regex
大小写敏感的正则表达式匹配。
它要求数据库支持正则表达式语法,而 SQLite 却没有内建正则表达式支持,因此 SQLite 的这个特性是由一个名为 REGEXP 的 Python 方法实现的,所以要用到 Python 的正则库 re.
Entry.objects.get(title__regex=r'^(An?|The) +')
等价于 SQL:
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle
SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite iregex
忽略大小写的正则表达式匹配。 四、范围匹配
gt 大于: Blog.objects.filter(id__gt=3)
gte 大于等于.
lt 小于.
lte 小于等于.
ne 不等于.
in 位于给定列表中: Blog.objects.filter(id__in=[1,3,5])
range 范围测试: Blog.objects.filter(name__range=('blog1','blog5')) 日期匹配:
year 对 date/datetime 字段, 进行精确的 年 匹配:Polls.objects.filter(pub_date__year=2005).
month
day
hour
minute
second 空值匹配
isnull True/False; 做 IF NULL/IF NOT NULL 查询:Blog.objects.filter(name__isnull=True)

d、 复杂查询条件,使用Q 对象进行复杂的查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。

Q对象有两种使用方式,一种使用Tree模式。另一种是使用"|"和"&"符号进行与或操作。

Q构建搜索条件
from django.db.models import Q
con = Q() q1 = Q()
q1.connector = 'OR'
q1.children.append(('id', 1))
q1.children.append(('id', 2))
#等价于Q(id=1) | Q(id=2) q2 = Q()
q2.connector = 'AND'
q2.children.append(('id', 1))
q2.children.append(('name__startswith', 'a'))
#等价于Q(id=1) | Q(name__startswith='a') con.add(q1, 'AND')
con.add(q2, 'AND') Q搜索可以和普通查询参数一起使用,但查询参数需要在最后。
Author.objects.filter(q1,id=26)

2.2关联字段CURD操作(一对一,一对多,多对多表关系操作)

一对一和多对多的表关系的增删改查
a1 = Author.objects.get(name="猴子")
a2 = Author.objects.get(name="苍松")
a3 = Author.objects.get(name="鲁迅")
p1=Publisher.objects.get(name="机械出版社")
p2=Publisher.objects.get(name="av") ==============正向关系操作===================================================

b1=Book(title="红楼梦",price=10)
b1.publisher=p1或者b1.publisher_id=1 #一对多
b1.save() 先保存book对象之后才能添加多对多关系
b1.authors.add(a1,a2)或者b1.authors=[a1,a2] #多对多
b1.save()
b1.publisher=None或者b1.publisher_id=None #一对多
b1.authors.remove(a1,a2) 实际上是删除关系表otest_book_authors中的一条数据 #多对多
b1.authors.clear() 清空所有关系 #多对多

查询
  Book.objects.filter(publisher__name=u"
机械出版社")  #一对多,使用双下划线
  Book.objects.filter(authors__name=u"苍松")  #多对多,使用双下划线
获取字段值对象
b2.publisher #一对多,对象下面的字段值继续使用.获取。例如b2.publisher.name
b1.authors.all() #多对多 ==============反向关系操作===================================================

p1.book_set.add(b1) #一对多,会更新现有的关系。(一个对象只能有一个外键)
a3.book_set.add(b1) #多对多

p1.book_set.remove(b1) #一对多
a3.book_set.remove(b1) #多对多
a3.book_set.clear() #多对多,清空所有关系

获取字段值对象

a2.book_set.all() #多对多
p1.book_set.all() #一对多 =============自定义中介模型方法===================================================
中介模型add、create 、remove方法不可用。但是clear() 方法却是可用的,它可以清空某个实例所有的多对多关系。

三、使用原始SQL语句

Django提供两种方法使用原始SQL进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种直接执行自定义的SQL语句。

1、使用Manager.raw()方法

Manager.raw(raw_query, params=None, translations=None)
raw_query SQL查询语句。
params 查询条件参数,是list或者dict
translations 字段映射表,是一个dict。
Manager.raw()将查询结果映射到类字段,默认情况下映射到同名字段。返回结果是一个RawQuerySet。
如果在其他的表中有一些Author数据,你可以很容易地把它们映射成Author实例。
手动指定字段映射字典。
方法一:使用AS,其他字段自动应设至Author表中的同名字段。
na=Author.objects.raw("select name AS newname, id from otest_author")
>>> na[]
<Author_Deferred_name: 苍松>
.
方法二:使用translations
name_map={"name":"newname}
na=Author.objects.raw("select * from otest_author",translations=name_map) params参数防止SQL注入
方法一:使用list
>>> na=Author.objects.raw("select * from otest_author where id =%s",[id])
>>> na[]
<Author: 苍松> 方法二:使用dict
注意:SQLite后端不支持字典,你必须以列表的形式传递参数。
字典使用%(key)s占位符(key替换成字典中相应的key值)
p_dict={"id":}
na=Author.objects.raw("select * from otest_author where id =%(id)s",p_dict)

2.直接执行自定义的SQL

有时Manager.raw()方法并不十分好用,你不需要将查询结果映射成模型,或者你需要执行UPDATE、 INSERT以及DELETE查询。

#单数据库
from django.db import connection
def my_custom_sql(self):
cursor = connection.cursor()
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
   connection.close()
return row #多数据库
from django.db import connections
cursor = connections['my_db_alias'].cursor()
# Your code here... 默认情况下,Python DB API会返回不带字段的结果,这意味着你得到的是一个列表,而不是一个字典。
def dictfetchall(cursor):
"Returns all rows from a cursor as a dict"
desc = cursor.description
return [
dict(zip([col[] for col in desc], row))
for row in cursor.fetchall()
] >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2");
>>> cursor.fetchall()
((54360982L, None), (54360880L, None)) >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2");
>>> dictfetchall(cursor)
[{'parent_id': None, 'id': 54360982L}, {'parent_id': None, 'id': 54360880L}]

四、分组和聚合

Avg        平均值
Count(expression, distinct=False) 计算个数。如果distinct=True,Count将只计算唯一的值。默认值为False。
Max 最大值
Min 最小值
Sum 求和
方法一:使用annotate方法,先分组(group by)再聚合
from django.db.models import Count, Min, Max, Sum,Avg
>>> Book.objects.values('publisher').annotate(counts_num=Count("*"))
[{'publisher': 1, 'counts_num': 2}, {'publisher': 3, 'counts_num': 1}] >>> Book.objects.values('publisher').annotate(Avg("price"))
[{'publisher': 1, 'price__avg': 12.5}, {'publisher': 3, 'price__avg': 11.0}] #得到分组的多个值列表
使用values('publisher')进行group by分组后,在使用聚合函数才有意义。
默认聚合名称filedname__聚合函数名,作为聚合字段名。 方法二:使用aggregate方法,先过滤再聚合
Book.objects.filter(publisher_id=1).aggregate(Count("id"))
{'id__count': 2} #得到单个值
参考文档:
  http://python.usyiyi.cn/django/index.html中文翻译1.8.2版中文不好的同学可以看这个 

Django之Model(一)--基础篇的更多相关文章

  1. Django学习笔记(基础篇)

    Django学习笔记(基础篇):http://www.cnblogs.com/wupeiqi/articles/5237704.html

  2. Django之Model操作进阶篇

    常用参数 null 数据库中字段是否可以为空 db_column 数据库中字段的列名 default 数据库中字段的默认值 primary_key 数据库中字段是否为主键 db_index 数据库中字 ...

  3. Python之路【第十六篇】:Django【基础篇】

    Python之路[第十六篇]:Django[基础篇]   Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...

  4. 01: Django基础篇

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  5. Django 【基础篇】

    前戏 python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #cod ...

  6. Python之路【第二十二篇】:Django之Model操作

    Django之Model操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...

  7. Django之Model组件

    Model组件在django基础篇就已经提到过了,本章介绍更多高级部分. 一.回顾 1.定义表(类) ##单表 from django.db import models class user(mode ...

  8. Django之模型层第一篇:单表操作

    Django之模型层第一篇:单表操作 一 ORM简介 ​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数 ...

  9. Django之模型层第二篇:多表操作

    Django之模型层第二篇:多表操作 一 表关系回顾 ​ 在讲解MySQL时,我们提到,把应用程序的所有数据都放在一张表里是极不合理的. ​ 比如我们开发一个员工管理系统,在数据库里只创建一张员工信息 ...

  10. DOM系列---基础篇

    DOM系列---基础篇   DOM (Document Object Model) 即文档对象模型, 针对 HTML 和 XML 文档的 API (应用程序接口) .DOM 描绘了一个层次化的节点树, ...

随机推荐

  1. 关于URLEncoder的编码和URLDecode解码

    在我们开发中,很多时候会遇见各种编码乱码的问题,其实这都是编码不一致的问题,如果你懂得了关于URLEncoder的编码和URLDecode解码,那么问题就会随之消失! 下面我们看看关于编码的代码: [ ...

  2. 一:Html基本结构

    1:什么是Html(HTML 概念)? Html是 HyperText mark-up Language 的缩写,意思是:超文本标记语言 2.HTML的发展史? 1991年:出现Html1.0(不存在 ...

  3. 10 个顶级 JavaScript 动画框架推荐

    使用JavaScript可以做出一些引人注目的动画效果,但通常不太容易实现.本文为你整理了10个非常优秀的JavaScript动画框架,使用它们你可以轻松实现动画效果.1. RaphaëlRaphaë ...

  4. 索引与优化like查询

    1. like %keyword    索引失效,使用全表扫描.但可以通过翻转函数+like前模糊查询+建立翻转函数索引=走翻转函数索引,不走全表扫描. 2. like keyword%    索引有 ...

  5. 正则转nfa:完成

    太累了,感觉不会再爱了.问题已经解决,具体的懒得说了. #include "regular_preprocess.h" //这个版本终于要上nfa了,好兴奋啊 //由于连个节点之间 ...

  6. 访问iPhone通讯录的问题

    每个APP只显示一次上图的提示,即使卸载APP也不显示.如果想再次显示提示,可进入 设置-->通用-->还原-->还原位置与隐私,即可. 而且在ios6中文环境下,访问通讯录会出现错 ...

  7. Log4.net使用配置

    开发中经常使用到日志记录功能,Log4.net可以将日志记录到文件中,也可以记录到数据库中,使用非常方便,之前也一直在用,最近也参照了一下网上的资料,想简单总结一下 本文重在通过通用日志类来使用Log ...

  8. js中的相等与不等运算

    如果其中一个操作数的类型为 Boolean ,那么,首先将它转换为数字类型,false 转换为 0, true 将转换为 1. 如果其中一个操作数的类型是字符串,另外一个为数字类型,那么,将字符串转换 ...

  9. wsus安装与部署——下

    转载请注明原出处 write by xiaoyang 一.            测试 1.         使用客户机或者在域环境下编辑GPO打开组策略 2.         配置自动更新 3.   ...

  10. iOS 最新版 CocoaPods 的安装使用

    当在开发iOS应用时,会经常使用到很多的第三方开源类库,一般的方法是直接从GitHub下载,然后拖到项目中使用,如果该开源类库不依赖其他的类库,就可以直接使用:如果该开源类库还依赖一些其他的类库,则需 ...