博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django之Model(一)--基础篇
阅读量:6432 次
发布时间:2019-06-23

本文共 18141 字,大约阅读时间需要 60 分钟。

 0、数据库配置

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

sqlite    django默认使用sqlite的数据库,默认自带sqlite的数据库驱    引擎名称:django.db.backends.sqlite3mysql    引擎名称: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 modelsclass Publisher(models.Model):    name = models.CharField(max_length=30, verbose_name="名称")    website = models.URLField()    # book_set     反向关联一对多字段的Book    def __unicode__(self):        return self.nameclass Author(models.Model):    name = models.CharField(max_length=30)    # authordetail  反向关联一对一字段AuthorDetail表    # book_set      反向关联一对多字段的Book    def __unicode__(self):        return self.nameclass AuthorDetail(models.Model):    sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))    author = models.OneToOneField(Author)    # author_id隐藏字段,正向关联一对一字段的Author对象的idclass 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-8from __future__ import unicode_literalsfrom django.db import modelsclass Publisher(models.Model):    name = models.CharField(max_length=30, verbose_name="名称")    website = models.URLField()    def __unicode__(self):        return self.nameclass Author(models.Model):    name = models.CharField(max_length=30)    def __unicode__(self):        return self.nameclass 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.titleclass Book2Author(models.Model):    book = models.ForeignKey(Book)    author = models.ForeignKey(Author)    groupname = models.CharField(max_length=100)#默认多对多关系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=True4、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_places8、models.EmailField  字符串类型(正则表达式邮箱) =varchar  对字符串进行正则表达式9、models.FloatField  浮点类型 = double10、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  正Integer16、models.PositiveSmallIntegerField  正smallInteger17、models.SlugField  减号、下划线、字母、数字18、models.SmallIntegerField  数字  数据库中的字段有:tinyint、smallint、int、bigint19、models.TextField  字符串=longtext20、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、存在就获取,查询到结果多余一个出错MultipleObjectsReturnedret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)ret:(
, False)b、不存在就创建ret=Author.objects.get_or_create(name=u'徐志摩',defaults=updated_values)ret:(
, True)方法五:存在就更新,不存在就创建update_or_create(defaults=None, **kwargs)a、存在就更新updated_values={
"name":u"猴王"}ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子")ret:(
, False)根据给出的查询条件name=u"猴子"查找对象,查询到结果就使用defaults字典去更新对象。b、不存在就创建ret=Author.objects.update_or_create(defaults=updated_values,name=u"猴子1")ret:(
, 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:
, 2:
, 3:
} 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 FBook.objects.filter(id=1).update(price=F('price')+10)

b、查询结果为QuerySet

 常用方法:

1、filter(**kwargs)    过滤,返回一个新的QuerySet,包含与给定的查询参数匹配的对象。    >>>q=Author.objects.filter(name=u"苍松")    >>> q    [
]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 [
,
,
,
,
,
,
] >>> q=Author.objects.order_by("-name") >>> q [
,
,
,
,
,
,
]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)
设置步长值后,获得到List类型值。触发数据库查询>>> a=Author.objects.all()[::2]>>> type(a)
使用索引,数据对象,触发数据库查询>>> Author.objects.all()[0]  #等价于Author.objects.all()[0:1].get()
查看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) +'; -- SQLiteiregex    忽略大小写的正则表达式匹配。四、范围匹配    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[0]    
. 方法二:使用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]
方法二:使用dict 注意:SQLite后端不支持字典,你必须以列表的形式传递参数。 字典使用%(key)s占位符(key替换成字典中相应的key值) p_dict={
"id":1} 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 connectiondef 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版中文不好的同学可以看这个 

 

转载于:https://www.cnblogs.com/tkqasn/p/5933261.html

你可能感兴趣的文章
core data 基础操作
查看>>
ORM框架Hibernate (四) 一对一单向、双向关联映射
查看>>
20140616 科技脉搏 -最大颠覆来自创业公司与边缘产业
查看>>
offsetLeft, offsetTop以及postion().left , postion().top有神马区别
查看>>
数据库中触发器before与after认识
查看>>
手动露天广场和立方体
查看>>
随机选择
查看>>
【Java并发编程三】闭锁
查看>>
分布式事务中遇到的 “与基础事务管理器的通信失败”的解决方法
查看>>
让你的Git水平更上一层楼的10个小贴士
查看>>
c++ string 之 find_first_not_of 源码
查看>>
mybatis中的#和$的区别
查看>>
ubuntu下搭建NDK环境
查看>>
MessageDigest简单介绍
查看>>
webpack window 使用sass来编译css样式
查看>>
D3 & Data Visualization in Ext JS
查看>>
java通过UUID生成16位唯一订单号
查看>>
001-web基本程序搭建
查看>>
函数指针和指针函数
查看>>
借力AI 极验如何构建下一代业务安全?
查看>>