码迷,mamicode.com
首页 > 其他好文 > 详细

Django之models之查询表

时间:2017-12-11 18:55:46      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:djang   author   接下来   article   one   sof   bsp   用两个   any   

单表查询

查询相关API:

<1> all():                 查询所有结果    # 返回的QuerySet类型
 
<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象   #返回的QuerySet类型
 
<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,  #返回的models对象
                           如果符合筛选条件的对象超过一个或者没有都会抛出错误。
 
<5> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象  #返回的QuerySet类型 
 
<4> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列  #返回的QuerySet类型 
                           model的实例化对象,而是一个可迭代的字典序列
 
<9> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列  #返回的QuerySet类型 
 
<6> order_by(*field):      对查询结果排序  
 
<7> reverse():             对查询结果反向排序
 
<8> distinct():            从返回结果中剔除重复纪录
 
<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
 
<11> first():              返回第一条记录  #返回的models对象
<12> last(): 返回最后一条记录  #返回的models对象
<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False

双下划线之单表查询

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
 
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
 
models.Tb1.objects.filter(id__range=[1, 2])      # 范围bettwen and
 
startswith,istartswith, endswith, iendswith 

基于对象的跨表查询(使用的是sql中的子查询语句)

一对多查询(Publish 与 Book)

正向查询(按字段:publish):

# 查询nid=1的书籍的出版社所在的城市
book_obj=Book.objects.get(nid=1)
print(book_obj.publish.city) # book_obj.publish 是nid=1的书籍对象关联的出版社对象  

反向查询(按表名:book_set):

# 查询 人民出版社出版过的所有书籍
 
    publish=Publish.objects.get(name="人民出版社")
 
    book_list=publish.book_set.all()  # 与人民出版社关联的所有书籍对象集合
 
    for book_obj in book_list:
        print(book_obj.title)

总结: 

  对于正向查询来说,使用子查询直接 点(.)自己类属性就可以关联到对应的出版社对象

  对于反向查询来说,使用需要,点(.)所要查询的模型名加上双下划set ( 类名__set   )

什么是正向? 什么是反向?

正向就是你查询的基表有外键字段,那么就是正向的,反之就是反向

一对一查询(Author 与 AuthorDetail)

正向查询(按字段:authorDetail):

# 查询egon作者的手机号
 
    author_egon=Author.objects.get(name="egon")
    print(author_egon.authorDetail.telephone)

反向查询(按表名:author):

# 查询所有住址在北京的作者的姓名
 
    authorDetail_list=AuthorDetail.objects.filter(addr="beijing")
 
    for obj in authorDetail_list:
        print(obj.author.name)

多对多查询 (Author 与 Book)

正向查询(按字段:authors):

# 金瓶眉所有作者的名字以及手机号
 
    book_obj=Book.objects.filter(title="金瓶眉").first()
 
    authors=book_obj.authors.all()
 
    for author_obj in authors:
 
        print(author_obj.name,author_obj.authorDetail.telephone)

反向查询(按表名:book_set):

# 查询egon出过的所有书籍的名字
 
    author_obj=Author.objects.get(name="egon")
    book_list=author_obj.book_set.all() #与egon作者相关的所有书籍
 
    for book_obj in book_list:
        print(book_obj.title)

注意:

你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Article model 中做一下更改: publish = ForeignKey(Blog, related_name=‘bookList‘),那么接下来就会如我们看到这般:

# 查询 人民出版社出版过的所有书籍
 
   publish=Publish.objects.get(name="人民出版社")
 
   book_list=publish.bookList.all()  # 与人民出版社关联的所有书籍对象集合

基于双下划线的跨表查询 ( join查询 )

Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止。

关键点:正向查询按字段,反向查询按表名。

# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)

    # 正向查询 按字段:publish

    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","price")

    # 反向查询 按表名:book

    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__price")



# 练习2: 查询egon出过的所有书籍的名字(多对多)

    # 正向查询 按字段:authors:
    queryResult=Book.objects
            .filter(authors__name="yuan")
            .values_list("title")

    # 反向查询 按表名:book
    queryResult=Author.objects
              .filter(name="yuan")
              .values_list("book__title","book__price")


# 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名


    # 正向查询
    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","authors__name")
    # 反向查询
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__authors__age","book__authors__name")


# 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

    queryResult=Book.objects
            .filter(authors__authorDetail__telephone__regex="151")
            .values_list("title","publish__name")

注意:

反向查询时,如果定义了related_name ,则用related_name替换表名,例如: publish = ForeignKey(Blog, related_name=‘bookList‘):

技术分享图片
# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)
 
    # 反向查询 不再按表名:book,而是related_name:bookList
 
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("bookList__title","bookList__price")
View Code

聚合查询与分组查询

聚合:aggregate(*args, **kwargs)

# 计算所有图书的平均价格
    >>> from django.db.models import Avg
    >>> Book.objects.all().aggregate(Avg(price))
    {price__avg: 34.35}

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它

>>> Book.objects.aggregate(average_price=Avg(price))
{average_price: 34.35}

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg(price), Max(price), Min(price))
{price__avg: 34.35, price__max: Decimal(81.20), price__min: Decimal(12.99)}

分组:annotate()

为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

统计每一本书的作者个数

bookList=Book.objects.annotate(authorsNum=Count(authors))
for book_obj in bookList:
    print(book_obj.title,book_obj.authorsNum)

统计每一个出版社的最便宜的书

publishList=Publish.objects.annotate(MinPrice=Min("book__price"))
 
for publish_obj in publishList:
    print(publish_obj.name,publish_obj.MinPrice)

根据一本图书作者数量的多少对查询集 QuerySet进行排序:

Book.objects.annotate(num_authors=Count(authors)).order_by(num_authors)

 

Django之models之查询表

标签:djang   author   接下来   article   one   sof   bsp   用两个   any   

原文地址:http://www.cnblogs.com/wangyuanming/p/8024072.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!