django默认支持sqlite,mysql, oracle,postgresql数据库。Django链接数据库默认编码使用UTF8,使用中文不须要特别设置。html
sqlite
django默认使用sqlite的数据库,默认自带sqlite的数据库驱
引擎名称:django.db.backends.sqlite3
mysql
引擎名称:django.db.backends.mysql
mysql引擎配置:python
'defaults': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'127.0.0.1',
'USER':'root',
'PASSWORD':'',
} mysql
mysql引擎底层驱动的py3支持问题:git
mysql驱动程序 MySQLdb(mysql python),Django默认使用改驱动,但改驱动在python3下存在兼容性问题。所以使用PyMySQL。 PyMySQL(纯python的mysql驱动程序) mysql驱动python3解决方法 找到项目名文件下的__init__,在里面写入: import pymysql pymysql.install_as_MySQLdb()
下面这个模型类将做为本篇博客的基础模型,全部的实例都基于此。web
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-8 from __future__ import unicode_literals from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30, verbose_name="名称") website = models.URLField() def __unicode__(self): return self.name class Author(models.Model): name = models.CharField(max_length=30) def __unicode__(self): return self.name class AuthorDetail(models.Model): sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),)) author = models.OneToOneField(Author) class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author,through='Book2Author') publisher = models.ForeignKey(Publisher) price=models.DecimalField(max_digits=5,decimal_places=2,default=10) def __unicode__(self): return self.title class Book2Author(models.Model): book = models.ForeignKey(Book) author = models.ForeignKey(Author) groupname = models.CharField(max_length=100) #默认多对多关系Django自动为咱们建立了一张中间表,仅提供3个字段,两个关联表的外键字段和一个id字段。 #这种使用自定义中间表的方式,使得咱们能够自定义的为中间表添加额外的字段。当咱们须要为多对多关系提供额外字段时,用此方式。
模型表建立和更新的时候是要使用数据库迁移命令,使模型类的改变同步到数据库。正则表达式
makemigrations #建立变动记录
migrate #同步到数据库
名词说明:sql
正向查询,从定义关系字段的类中去查询关系对象的值或值的集合。举个栗子:从AuthorDetail类中查询关联字段author对象的值。数据库
反向查询,从本类中查询被关联对象中的值或值的集合。举个栗子:从Author对象中查询被关联字段AuthorDetail对象的值。express
一、models.AutoField 自增列 = int(11) 若是没有的话,默认会生成一个名称为 id 的列,若是要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。 2、models.CharField 字符串字段 必须 max_length 参数 三、models.BooleanField 布尔类型=tinyint(1) 不能为空,Blank=True 四、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar 继承CharField,因此必须 max_lenght 参数 5、models.DateField 日期类型 date 对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次建立添加,以后的更新再也不改变。 6、models.DateTimeField 日期类型 datetime 同DateField的参数 七、models.Decimal 十进制小数类型 = decimal 必须指定整数位max_digits和小数位decimal_places 八、models.EmailField 字符串类型(正则表达式邮箱) =varchar 对字符串进行正则表达式 九、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、ipv四、ipv6 验证时,会根据设置报错 14、models.NullBooleanField 容许为空的布尔类型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 减号、下划线、字母、数字 18、models.SmallIntegerField 数字 数据库中的字段有:tinyint、smallint、int、bigint 1九、models.TextField 字符串=longtext 20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正则表达式 22、models.BinaryField 二进制 23、models.ImageField 图片 2四、models.FilePathField 文件
一、null=True 数据库中字段是否能够为空 二、blank=True django的 Admin 中添加数据时是否可容许空值 三、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中字段的显示名称 九、name|db_column 数据库中的字段名称 十、unique=True 不容许重复 十一、db_index = True 数据库索引 十二、editable=True 在Admin里是否可编辑 1三、error_messages=None 错误提示 1四、auto_created=False 自动建立 15、help_text 在Admin中提示帮助信息 1六、validators=[] 自定义数据格式验证 1七、upload-to 上传文件路径
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一同设置。
一、增django
方法一: 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优先。
二、删
使用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()
三、改
方法一: update(**kwargs)返回更新的行数,批量修改 ret=Author.objects.filter(name='秋雨').update(name="陶渊明") 方法二: 单条修改 a7=Author.objects.get(name="清风") a7.name=u"宋清风" a7.save()
四、查
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
经常使用方法:
一、filter(**kwargs) 过滤,返回一个新的QuerySet,包含与给定的查询参数匹配的对象。 >>>q=Author.objects.filter(name=u"苍松") >>> q [<Author: 苍松>] 二、exclude(**kwargs) 反过滤,返回一个新的QuerySet,它包含不知足给定的查找参数的对象。功能与filter相反。 三、values(*fields) 返回一个新的QuerySet,但迭代时返回字典而不是模型实例对象。 *fields表示须要取哪些字段,空表示取全部字段。 >>> q=Author.objects.values("id") >>> q [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 18}, {'id': 22}, {'id': 24}] 四、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全部对象。 六、select_related(*field) 返回一个QuerySet,使用JOIN语句连表查询。它会在执行查询时自动跟踪外键关系,一次读取全部外键关联的字段,并尽量地深刻遍历外键链接,以减小数据库的查询。但数据关系链复杂的查询须要慎用。仅对外键生效。 七、prefetch_related(*field) prefetch_related()的解决方法是,分别查询每一个表,而后用Python处理他们之间的关系。外键和多对多都生效。 八、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()才有效果。 十、distinct([*fields]) 去重复。返回一个在SQL 查询中使用SELECT DISTINCT 的新QuerySet。
一、dates(field, kind, order='ASC') field 是你的 model 中的 DateField 字段名称。 kind 是 “year”, “month” 或 “day” 之一。 每一个 datetime.date对象都会根据所给的 type 进行截减。 “year” 返回全部时间值中非重复的年分列表。 “month” 返回全部时间值中非重复的年/月列表。 “day” 返回全部时间值中非重复的年/月/日列表。 order, 默认是 ‘ASC’,只有两个取值 ‘ASC’ 或 ‘DESC’。它决定结果如何排序。 二、datetimes(field, kind, order=’ASC’) 返回一个 DateTimeQuerySet,参数与dates相似,多了"hour", "minute" ,"second" 3、none() 返回一个 EmptyQuerySet,它是一个运行时只返回空列表的 QuerySet。它常常用在这种场合:你要返回一个空列表,可是调用者却须要接收一个 QuerySet 对象。 四、defer(*fields) 将不想载入的字段的名称传给 defer() 方法,就能够作到延后载入。 在某些数据复杂的环境下,你的 model 可能包含很是多的字段,可能某些字段包含很是多的数据(好比,文档字段),或者将其转化为Python对象会消耗很是多的资源。在这种状况下,有时你可能并不须要这种字段的信息,那么你可让 Django 不读取它们的数据。 五、only(*fields) only() 方法或多或少与 defer() 的做用相反。若是你在提取数据时但愿某个字段不该该被延后载入,而应该当即载入,那么你就能够作使用 only()方法。 6、多数据库切换using(alias) 单独使用无心义,配合其余查询集方法一块儿使用。 Author.objects.using('backup') 七、表锁定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) 1、精确匹配 exact 精确匹配: Blog.objects.get(id__exact=1) iexact 忽略大小写的精确匹配,Blog.objects.filter(name__iexact='blog7') 2、模糊匹配 (模糊匹配,仅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. 3、正则匹配 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 忽略大小写的正则表达式匹配。 4、范围匹配 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)
一对一和多对多的表关系的增删改查 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() 方法倒是可用的,它能够清空某个实例全部的多对多关系。
Django提供两种方法使用原始SQL进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另外一种直接执行自定义的SQL语句。
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[0] <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[0] <Author: 苍松> 方法二:使用dict 注意:SQLite后端不支持字典,你必须以列表的形式传递参数。 字典使用%(key)s占位符(key替换成字典中相应的key值) p_dict={"id":1} na=Author.objects.raw("select * from otest_author where id =%(id)s",p_dict)
有时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[0] 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版中文很差的同窗能够看这个