Django-ORM查询

1.单表查询--必知必会的13条

函数名 说明 用法 返回值 注意事项
all() 查询所有 Book.object.all() queryset -
filter(*fields) 条件查询 Book.object.filter(title="三国演义") queryset -
get(*fields) 条件查询 Book.object.get(title="三国演义") model_obj 查询结果没有或者多个会报错
first() 第一条 Book.object.filter(title="三国演义").first() model_obj -
last() 最后一条 Book.object.filter(title="三国演义").last() model_obj -
order_by(*fields) 排序 Book.objects.all().order_by("price") queryset .order_by("-price")倒叙order_by("-price","pub_date")多条件排序
exclude(*fields) 排除 Book.objects.exclude(price=123) queryset -
count() 计数/查询条数 Book.objects.all().count() int -
reverse() 反向排序 Book.objects.all().order_by("title").reverse() queryset -
exists() 查询条件时候存在数据 Book.objects.all().exists() bool -
values(*fields) 返回需要的的字段 Book.objects.all().values("title","price") dict -
values_list(*fields) 返回需要的的字段的数据 Book.objects.all().values_list("title", "price") tuple -
distinc() 去重 Book.objects.all().values("title").distinc() dict / tuple 一般会与values、values_list组合使用

2.单表查询--模糊查询

  • 使用双下划线 '__'
字段名 说明 用法 注意事项
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__startwith 以什么开始
__istartwith 以什么开始不区分大小写
__endwith 以什么结束
__iendwith 以什么结束 不区分大小写
__contains 包含
__icontains 包含什么 不区分大小写
__in 在什么里面的
__range 在什么范围之间的
__year 年份等与多少的
__month 月份等于多少的

下面查询用到的表关系

class Book(models.Model):

    nid = models.AutoField(primary_key=True)  # 主键 自增
    title = models.CharField(max_length=64,verbose_name="书籍名称")  # 字符形式 最大长度32
    price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name="书籍价格")  # 浮点型999999.99  最大长度 8位  小数点后2位
    comment_count = models.CharField(max_length=32, verbose_name="评论数量")
    poll_count = models.CharField(max_length=32, verbose_name="点赞数量")
    pub_date = models.DateTimeField(verbose_name="出版日期")  # "2012-12-12"
    publish = models.ForeignKey(to="Publish",on_delete=models.CASCADE, verbose_name="正向关联出版社字段")  # 级联删除
    authors = models.ManyToManyField(to="Author", verbose_name="正向关联作者字段")

    def __str__(self):
        return self.title  # queryset  显示的名称

    class Meta:
        verbose_name="书籍表"


class Publish(models.Model):

    nid = models.AutoField(primary_key=True, verbose_name="主键")
    name = models.CharField(max_length=32, verbose_name="出版社名称")
    email = models.CharField(max_length=32, verbose_name="出版社邮箱")

    def __str__(self):
        return self.name  # queryset  显示的名称

    class Meta:
        verbose_name = "出版社表"


class Author(models.Model):

    name = models.CharField(max_length=32, verbose_name="作者名字")
    age = models.IntegerField(verbose_name="年龄")
    email = models.CharField(max_length=32, verbose_name="邮箱")
    ad = models.OneToOneField(to="AuthorDrtail",on_delete=models.CASCADE,verbose_name="正向关联的作者详情字段")

    def __str__(self):
        return self.name  # queryset  显示的名称

    class Meta:
        verbose_name = "作者表"

class AuthorDrtail(models.Model):

    addr = models.CharField(max_length=32, verbose_name="作者住址")
    tel = models.IntegerField(verbose_name="作者手机号")

    def __str__(self):
        return self.tel  # queryset  显示的名称

    class Meta:
        verbose_name = "作者详情表"

3.表关联查询 基于对象的跨表查询(子查询)

  • 一对多
            正向查询: 按字段 book.publish
    Book    -----------------------------  Publish
            反向查询: 表名的小写_set.all()
# 查询python出版社的名字 和邮箱   书查出版社   -对多查询
    book_obj = Book.objects.filter(title="python").first()
    publish_obj = book_obj.publish
    publish_obj.name
    publish_obj.email

    # 查询苹果出版社 出版的所有书籍名称
    pub_obj = Publish.objects.get(name="苹果出版社")
    publish_obj.book_set.all().values("title")  # queryset

    # 查询 jack 出版的所有书籍名称
    author = Author.objects.filter(name="Jack").first()
    author.book_set.all()
  • 多对多
            正向查询  book.author.all()
    Book -----------------------------------Author
            反向查询  表名小写_set.all()  jack.book_set.all().values("age")

  • 一对一
            正向查询 author.ad
    Author ----------------------- AuthorDetail
            反向查询 ad.author    : ad.表名小写

4.表关联查询 基于双下划线 __ 的跨表查询(join 即 一次查询)


"""
    一对多
            正向查询 按字段
    Book    ---------------------   Publish
            反向查询 按表名小写
"""
    # 查询书籍名为 python 的出版社的 名字  一对多
    Book.objects.filter(title="python").values("publish__name")  # 正向查询
    Publish.objects.first(book__title="python").values('name')  # 反向查询

    # 查询 北京出版社 出版社的书籍 名称 一对多
    Publish.objects.filter(name="北京出版社").values('book__title')
    Book.objects.filter(pulish__name='北京出版社').values('title')



    # 查询 python 这本书的作者的年龄  多对多
    Book.objects.filter(title='python').values("authors__age")
    Author.objects.filter(book__title='python').values('age')
    return HttpResponse("查询成功")

    # 查询 Jack 出版的书籍的 名称  多对多
    Author.objects.filter(name='Jack').values("book__title")
    Book.objects.filter(authors__name='Jack').values('title')

    # 查询 Jack的手机号  一对一
    Author.objects.filter(name='Jack').values("ad__tel")
    AuthorDrtail.objects.filter(author__name="Jack").values("tel")
    
    # 查询手机号为131 的作者的名字  一对一
    AuthorDrtail.objects.filter(tel=131).values('author__name')
    Author.objects.filter(ad__tel=131).values('name')

5. 连续跨表查询

# 查询 人民出版社 出版过的多有书籍的名字以及作者的名字
Publish.objects.filter(name="人民出版社").values("book__title","book__authors__name")
Book.objects.filter(publish__name="人民出版社").values("title","authors__name") Author.objects.filter(book__publish__name="人民出版社").values('book__title','name')
 # 手机号以 151 开头的作者出版过的所有书籍名称以及出版社的名称
AuthorDrtail.objects.filter(tel__startwith=151).values('author__book__title',"author__book__publish__name")
Author.objects.filter(ad__tel__startwith=151).values("book__title",'book__publish__name')

6. 聚合 分组查询

  • 导入集合函数from django.db.models import Avg,Max,Sum, Min, Count
##############    聚合max min count min avg   #########

    from django.db.models import Avg,Max,Sum, Min, Count
    # 查询多有书籍的平均价
    Book.objects.all().aggregate(priceAvg=Avg("price"))  # {"avg_price":123.00}  可以重命名
    # 查询是多有书籍的个数
    Book.objects.all().aggregate(c=Count("nid"))  # {"c":4}

    ##############    分组(group by)查询    #########

    # 查询书籍表每个出版社id以及对应的个数
    # key : annotate  前 select 那个字段就按照 那个字段group by
    Book.objects.values('publish_id').annotate(c=Count(1))  # 返回值
    '''
    select Count(1)m from book GROUP BY publish_id
    '''

    # 跨表查询
    #查询出版社出版的名称以及对应的书籍平均价格
    Publish.objects.values('name').annotate(avg_price=Avg("book__price"))  # book__price Book表中的price
# 简单的写法 现联表查询出所有  再选择要筛选的字段
    Publish.objects.annotate(avg_price='book_price').values('name',"avg_peice")

6. F(获取字段值) 与 Q (关系) 查询

    ##################  F     #################
    from django.db.models import F, Q

    # 查询 评论数 大于 点赞数的 书籍名称
    Book.objects.filter(comment_count__gt=F(poll_count)).values("title")

    # 查询评论数 大于 2倍点赞数的书籍名称
    Book.objects.filter(commnet_count__gt=F(poll_count)*2).values("title")

    # 批量有规律的更新  所有的书籍几个提升100 或者 提升1倍
    Book.objects.all().update(price=100+F("price"))
    Book.objects.all().update(price=F("price")*2)


##################  Q  查询   #################
# 查询价格大于 300 或者 评论数大于3000的书籍

    """
    运算符号   &与   |或   ~非
    """

    Book.objects.filter(Q(price__gt=300)|Q(comment_count__gt=3000))
    Book.objects.filter(~Q(Q(price__gt=300)|Q(comment_count__gt=3000)&Q(poll_count__lt=2000)))

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,865评论 6 518
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,296评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 169,631评论 0 364
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,199评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,196评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,793评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,221评论 3 423
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,174评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,699评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,770评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,918评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,573评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,255评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,749评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,862评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,364评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,926评论 2 361

推荐阅读更多精彩内容