【目录】

一、单表查询(增删改查)

二、常见的十几种查询方法

三、神奇的双下划线查询

四、外键字段的增删改查

五、跨表查询(重点)

(一)子查询

(二)联表查询

六、聚合查询

七、分组查询

八、F与Q查询

九、Django中如何开启事务

十、orm中常用字段及参数

十一、数据库查询优化 (only与defer、select_related与prefetch_related)

一、单表查询(增删改查)

#django自带的sqlite3数据库对日期格式不是很敏感 处理的时候容易出错#增

#res = models.User.objects.create(name='jason',age=18,register_time='2002-1-21')

#print(res)

#import datetime

#ctime = datetime.datetime.now()

#user_obj = models.User(name='egon',age=84,register_time=ctime)

#user_obj.save()

#删

#res = models.User.objects.filter(pk=2).delete()

#print(res)

"""pk会自动查找到当前表的主键字段 指代的就是当前表的主键字段

用了pk之后 你就不需要指代当前表的主键字段到底叫什么了

uid

pid

sid

..."""

#user_obj = models.User.objects.filter(pk=1).first()

#user_obj.delete()

#修改

#models.User.objects.filter(pk=4).update(name='egonDSB')

#user_obj = models.User.objects.get(pk=4)

#user_obj = models.User.objects.filter(pk=6)

"""get方法返回的直接就是当前数据对象

但是该方法不推荐使用

一旦数据不存在该方法会直接报错

而filter则不会

所以我们还是用filter"""

#user_obj.name = 'egonPPP'

#user_obj.save()

二、常见的十几种查询方法

(一)必知必会13条

#必知必会13条

#1.all() 查询所有数据

#2.filter() 带有过滤条件的查询

#3.get() 直接拿数据对象 但是条件不存在直接报错

#4.first() 拿queryset里面第一个元素

#res = models.User.objects.all().first()

#print(res)

#5.last()

#res = models.User.objects.all().last()

#print(res)

#6.values() 可以指定获取的数据字段 select name,age from ... 列表套字典

#res = models.User.objects.values('name','age') #

#print(res)

#7.values_list() 列表套元祖

#res = models.User.objects.values_list('name','age') #

#print(res)

#"""

## 查看内部封装的sql语句

#上述查看sql语句的方式 只能用于queryset对象

#只有queryset对象才能够点击query查看内部的sql语句

# #"""

#8.distinct() 去重

#res = models.User.objects.values('name','age').distinct()

#print(res)

"""去重一定要是一模一样的数据

如果带有主键那么肯定不一样 你在往后的查询中一定不要忽略主键"""

#9.order_by()

#res = models.User.objects.order_by('age') # 默认升序

#res = models.User.objects.order_by('-age') # 降序

# #print(res)

#10.reverse() 反转的前提是 数据已经排过序了 order_by()

#res = models.User.objects.all()

#res1 = models.User.objects.order_by('age').reverse()

#print(res,res1)

#11.count() 统计当前数据的个数

#res = models.User.objects.count()

#print(res)

#12.exclude() 排除在外

#res = models.User.objects.exclude(name='jason')

#print(res)

#13.exists() 基本用不到因为数据本身就自带布尔值 返回的是布尔值

#res = models.User.objects.filter(pk=10).exists()

#print(res)

(二)测试脚本

"""当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式

而是直接写一个测试脚本即可

脚本代码无论是写在应用下的tests.py还是自己单独开设py文件都可以"""

#测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行

importosimportsysif __name__ == "__main__":

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day64.settings")importdjango

django.setup()#在这个代码块的下面就可以测试django里面的单个py文件了

(三)查看内部sql语句的方式

#方式1

res = models.User.objects.values_list('name','age')

#

print(res.query)

queryset对象才能够点击query查看内部的sql语句#方式2:所有的sql语句都能查看#去配置文件中配置一下即可

LOGGING ={'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',

},

},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',

},

}

}

三、神奇的双下划线查询

#神奇的双下划线查询

#1 年龄大于35岁的数据

#res = models.User.objects.filter(age__gt=35)

#print(res)

#2 年龄小于35岁的数据

#res = models.User.objects.filter(age__lt=35)

#print(res)

#大于等于 小于等于

#res = models.User.objects.filter(age__gte=32)

#print(res)

#res = models.User.objects.filter(age__lte=32)

#print(res)

#年龄是18 或者 32 或者40

#res = models.User.objects.filter(age__in=[18,32,40])

#print(res)

#年龄在18到40岁之间的 首尾都要

#res = models.User.objects.filter(age__range=[18,40])

#print(res)

#查询出名字里面含有s的数据 模糊查询

#res = models.User.objects.filter(name__contains='s')

#print(res)

# #是否区分大小写 查询出名字里面含有p的数据 区分大小写

#res = models.User.objects.filter(name__contains='p')

#print(res)

#忽略大小写

#res = models.User.objects.filter(name__icontains='p')

#print(res)

#res = models.User.objects.filter(name__startswith='j')

#res1 = models.User.objects.filter(name__endswith='j')

# #print(res,res1)

#查询出注册时间是 2020 1月

#res = models.User.objects.filter(register_time__month='1')

#res = models.User.objects.filter(register_time__year='2020')

四、外键字段的增删改查

(一)一对多外键增删改查

#一对多外键增删改查

#增

#1 直接写实际字段 id

#models.Book.objects.create(title='论语',price=899.23,publish_id=1)

#models.Book.objects.create(title='聊斋',price=444.23,publish_id=2)

#models.Book.objects.create(title='老子',price=333.66,publish_id=1)

#2 虚拟字段 对象

#publish_obj = models.Publish.objects.filter(pk=2).first()

#models.Book.objects.create(title='红楼梦',price=666.23,publish=publish_obj)

#删

#models.Publish.objects.filter(pk=1).delete() # 级联删除

#修改

#models.Book.objects.filter(pk=1).update(publish_id=2)

#publish_obj = models.Publish.objects.filter(pk=1).first()

#models.Book.objects.filter(pk=1).update(publish=publish_obj)

(二)多对多外键增删改查

#如何给书籍添加作者?

book_obj = models.Book.objects.filter(pk=1).first()#print(book_obj.authors) # 就类似于你已经到了第三张关系表了

#book_obj.authors.add(1) # 书籍id为1的书籍绑定一个主键为1 的作者

#book_obj.authors.add(2,3)

#author_obj = models.Author.objects.filter(pk=1).first()

#author_obj1 = models.Author.objects.filter(pk=2).first()

#author_obj2 = models.Author.objects.filter(pk=3).first()

#book_obj.authors.add(author_obj)

#book_obj.authors.add(author_obj1,author_obj2)

"""add给第三张关系表添加数据

括号内既可以传数字也可以传对象 并且都支持多个"""

#删

#book_obj.authors.remove(2)

#book_obj.authors.remove(1,3)

#author_obj = models.Author.objects.filter(pk=2).first()

#author_obj1 = models.Author.objects.filter(pk=3).first()

#book_obj.authors.remove(author_obj,author_obj1)

"""remove

括号内既可以传数字也可以传对象 并且都支持多个"""

#修改

#book_obj.authors.set([1,2]) # 括号内必须给一个可迭代对象

#book_obj.authors.set([3]) # 括号内必须给一个可迭代对象

#author_obj = models.Author.objects.filter(pk=2).first()

#author_obj1 = models.Author.objects.filter(pk=3).first()

#book_obj.authors.set([author_obj,author_obj1]) # 括号内必须给一个可迭代对象

"""set

括号内必须传一个可迭代对象,该对象内既可以数字也可以对象 并且都支持多个"""

#清空

#在第三张关系表中清空某个书籍与作者的绑定关系

book_obj.authors.clear()"""clear

括号内不要加任何参数"""

(三)正反向的概念

#正向#反向

外键字段在我手上那么,我查你就是正向

外键字段如果不在手上,我查你就是反向

book>>>外键字段在书那儿(正向)>>>publish

publish>>>外键字段在书那儿(反向)>>>book

一对一和多对多正反向的判断也是如此"""正向查询按字段

反向查询按表名小写

_set

..."""

五、跨表查询(重点)

(一)子查询(基于对象的跨表查询)

#1.查询书籍主键为1的出版社

#book_obj = models.Book.objects.filter(pk=1).first()

## 书查出版社 正向

#res = book_obj.publish

#print(res)

#print(res.name)

#print(res.addr)

#2.查询书籍主键为2的作者

#book_obj = models.Book.objects.filter(pk=2).first()

## 书查作者 正向

## res = book_obj.authors # app01.Author.None

#res = book_obj.authors.all()

# , ]>

# #print(res)

#3.查询作者jason的电话号码

#author_obj = models.Author.objects.filter(name='jason').first()

#res = author_obj.author_detail

#print(res)

#print(res.phone)

#print(res.addr)

"""在书写orm语句的时候跟写sql语句一样的

不要企图一次性将orm语句写完 如果比较复杂 就写一点看一点

正向什么时候需要加.all()

当你的结果可能有多个的时候就需要加.all()

如果是一个则直接拿到数据对象

book_obj.publish

book_obj.authors.all()

author_obj.author_detail"""

#4.查询出版社是东方出版社出版的书

#publish_obj = models.Publish.objects.filter(name='东方出版社').first()

#出版社查书 反向

#res = publish_obj.book_set # app01.Book.None

#res = publish_obj.book_set.all()

#print(res)

#5.查询作者是jason写过的书

#author_obj = models.Author.objects.filter(name='jason').first()

#作者查书 反向

#res = author_obj.book_set # app01.Book.None

#res = author_obj.book_set.all()

#print(res)

#6.查询手机号是110的作者姓名

#author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()

#res = author_detail_obj.author

#print(res.name)

"""基于对象

反向查询的时候

当你的查询结果可以有多个的时候 就必须加_set.all()

当你的结果只有一个的时候 不需要加_set.all()

自己总结出 自己方便记忆的即可 每个人都可以不一样"""

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

#基于双下划线的跨表查询

#1.查询jason的手机号和作者姓名

#res = models.Author.objects.filter(name='jason').values('author_detail__phone','name')

#print(res)

#反向

#res = models.AuthorDetail.objects.filter(author__name='jason') # 拿作者姓名是jason的作者详情

#res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__name')

#print(res)

#2.查询书籍主键为1的出版社名称和书的名称

#res = models.Book.objects.filter(pk=1).values('title','publish__name')

#print(res)

#反向

#res = models.Publish.objects.filter(book__id=1).values('name','book__title')

#print(res)

#3.查询书籍主键为1的作者姓名

#res = models.Book.objects.filter(pk=1).values('authors__name')

#print(res)

#反向

#res = models.Author.objects.filter(book__id=1).values('name')

#print(res)

#查询书籍主键是1的作者的手机号

#book author authordetail

#res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')

#print(res)

"""你只要掌握了正反向的概念

以及双下划线

那么你就可以无限制的跨表"""

六、聚合查询—— aggregate

聚合函数就是五个聚合函数的使用,通常都是配合【分组】一起使用的

首先应导入这五个聚合函数模块 :

from django.db.models import Max,Min,Sum,Count,Avg

#聚合查询 aggregate

"""聚合查询通常情况下都是配合分组一起使用的

只要是跟数据库相关的模块

基本上都在django.db.models里面

如果上述没有那么应该在django.db里面"""

from app01 importmodelsfrom django.db.models importMax,Min,Sum,Count,Avg#1 所有书的平均价格

#res = models.Book.objects.aggregate(Avg('price'))

#print(res)

#2.上述方法一次性使用

res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('pk'),Avg('price'))print(res)

七、分组查询

#分组查询 annotate

"""MySQL分组查询都有哪些特点

分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取了

严格模式

ONLY_FULL_GROUP_BY"""

from django.db.models importMax, Min, Sum, Count, Avg#1.统计每一本书的作者个数

#res = models.Book.objects.annotate() # models后面点什么 就是按什么分组

#res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')

"""author_num是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数"""

#res1 = models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')

#print(res,res1)

"""代码没有补全 不要怕 正常写

补全给你是pycharm给你的 到后面在服务器上直接书写代码 什么补全都没有 颜色提示也没有"""

#2.统计每个出版社卖的最便宜的书的价格(作业:复习原生SQL语句 写出来)

#res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')

#print(res)

#3.统计不止一个作者的图书

#1.先按照图书分组 求每一本书对应的作者个数

#2.过滤出不止一个作者的图书

#res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num')

#"""

#只要你的orm语句得出的结果还是一个queryset对象

#那么它就可以继续无限制的点queryset对象封装的方法

# #"""

#print(res)

#4.查询每个作者出的书的总价格

#res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')

#print(res)

"""如果我想按照指定的字段分组该如何处理呢?

models.Book.objects.values('price').annotate()

后续BBS作业会使用

你们的机器上如果出现分组查询报错的情况

你需要修改数据库严格模式(去掉严格模式)"""

八、F与Q查询

#F查询

#1.查询卖出数大于库存数的书籍

#F查询

"""能够帮助你直接获取到表中某个字段对应的数据"""

from django.db.models importF#res = models.Book.objects.filter(maichu__gt=F('kucun'))

#print(res)

#2.将所有书籍的价格提升500块

#models.Book.objects.update(price=F('price') + 500)

#3.将所有书的名称后面加上爆款两个字

"""在操作字符类型的数据的时候 F不能够直接做到字符串的拼接"""

from django.db.models.functions importConcatfrom django.db.models importValue

models.Book.objects.update(title=Concat(F('title'), Value('爆款')))#models.Book.objects.update(title=F('title') + '爆款') # 所有的名称会全部变成空白

#Q查询

#1.查询卖出数大于100或者价格小于600的书籍

#res = models.Book.objects.filter(maichu__gt=100,price__lt=600)

"""filter括号内多个参数是and关系"""

from django.db.models importQ#res = models.Book.objects.filter(Q(maichu__gt=100),Q(price__lt=600)) # Q包裹逗号分割 还是and关系

#res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600)) # | or关系

#res = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600)) # ~ not关系

#print(res) #

#Q的高阶用法 能够将查询条件的左边也变成字符串的形式

q =Q()

q.connector= 'or'q.children.append(('maichu__gt',100))

q.children.append(('price__lt',600))

res= models.Book.objects.filter(q) #默认还是and关系

print(res)

九、Django中如何开启事务

"""事务

ACID

原子性

不可分割的最小单位

一致性

跟原子性是相辅相成

隔离性

事务之间互相不干扰

持久性

事务一旦确认永久生效

事务的回滚

rollback

事务的确认

commit"""

#目前你只需要掌握Django中如何简单的开启事务#事务

from django.db importtransactiontry:

with transaction.atomic():#sql1

#sql2

...#在with代码快内书写的所有orm操作都是属于同一个事务

exceptException as e:print(e)print('执行其他操作')

十、orm中常用字段及参数

AutoField

主键字段 primary_key=True

CharField varchar

verbose_name 字段的注释

max_length 长度

IntegerField int

BigIntegerField bigint

DecimalField

max_digits=8decimal_places=2EmailFiled varchar(254)

DateField date

DateTimeField datetime

auto_now:每次修改数据的时候都会自动更新当前时间

auto_now_add:只在创建数据的时候记录创建时间后续不会自动修改了

BooleanField(Field)-布尔值类型

该字段传布尔值(False/True) 数据库里面存0/1TextField(Field)-文本类型

该字段可以用来存大段内容(文章、博客...) 没有字数限制

后面的bbs作业 文章字段用的就是TextField

FileField(Field)-字符类型

upload_to= "/data"给该字段传一个文件对象,会自动将文件保存到/data目录下然后将文件路径保存到数据库中/data/a.txt

后面bbs作业也会涉及#更多字段

直接参考博客:https://www.cnblogs.com/Dominic-Ji/p/9203990.html#django除了给你提供了很多字段类型之外 还支持你自定义字段

classMyCharField(models.Field):def __init__(self,max_length,*args,**kwargs):

self.max_length=max_length#调用父类的init方法

super().__init__(max_length=max_length,*args,**kwargs) #一定要是关键字的形式传入

defdb_type(self, connection):"""返回真正的数据类型及各种约束条件

:param connection:

:return:"""

return 'char(%s)'%self.max_length#自定义字段使用

myfield = MyCharField(max_length=16,null=True)#外键字段及参数

unique=True

ForeignKey(unique=True) ===OneToOneField()#你在用前面字段创建一对一 orm会有一个提示信息 orm推荐你使用后者但是前者也能用

db_index

如果db_index=True 则代表着为此字段设置索引

(复习索引是什么)

to_field

设置要关联的表的字段 默认不写关联的就是另外一张的主键字段

on_delete

当删除关联表中的数据时,当前表与其关联的行的行为。"""django2.X及以上版本 需要你自己指定外键字段的级联更新级联删除"""

十一、数据库查询优化 (only与defer、select_related与prefetch_related)

only与defer

select_related与prefetch_related"""orm语句的特点:

惰性查询

如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数

那么orm会自动识别 直接不执行"""

#only与defer#res = models.Book.objects.all()

#print(res) # 要用数据了才会走数据库

#想要获取书籍表中所有数的名字

#res = models.Book.objects.values('title')

#for d in res:

#print(d.get('title'))

#你给我实现获取到的是一个数据对象 然后点title就能够拿到书名 并且没有其他字段

#res = models.Book.objects.only('title')

#res = models.Book.objects.all()

#print(res) # , , , , ]>

#for i in res:

#print(i.title) # 点击only括号内的字段 不会走数据库

#print(i.price) # 点击only括号内没有的字段 会重新走数据库查询而all不需要走了

res= models.Book.objects.defer('title') #对象除了没有title属性之外其他的都有

for i inres:print(i.price)"""defer与only刚好相反

defer括号内放的字段不在查询出来的对象里面 查询该字段需要重新走数据

而如果查询的是非括号内的字段 则不需要走数据库了"""

#select_related与prefetch_related#select_related与prefetch_related 跟跨表操作有关

#res = models.Book.objects.all()

#for i in res:

#print(i.publish.name) # 每循环一次就要走一次数据库查询

#res = models.Book.objects.select_related('authors') # INNER JOIN

"""select_related内部直接先将book与publish连起来 然后一次性将大表里面的所有数据

全部封装给查询出来的对象

这个时候对象无论是点击book表的数据还是publish的数据都无需再走数据库查询了

select_related括号内只能放外键字段 一对多 一对一

多对多也不行"""

#for i in res:

#print(i.publish.name) # 每循环一次就要走一次数据库查询

res= models.Book.objects.prefetch_related('publish') #子查询

"""prefetch_related该方法内部其实就是子查询

将子查询查询出来的所有结果也给你封装到对象中

给你的感觉好像也是一次性搞定的"""

for i inres:print(i.publish.name)

参考阅读:

python框架django书籍_【2020Python修炼记】web框架之 Django的ORM语法相关推荐

  1. python框架django书籍_有Python基础,刚接触web框架的Django初学者。

    本文面向:有Python基础,刚接触web框架的Django初学者. 环境:windows7 python3.5.1 pycharm Django 1.10版 pip3 一.Django简介 百度百科 ...

  2. 使用双标记写html代码时如何进行嵌套,【2020Python修炼记】前端开发之 前端基础和HTML入门...

    发表于:2020-11-12 18:21 阅读: 119次 这篇教程主要讲解了[2020Python修炼记]前端开发之 前端基础和HTML入门,并附有相关的代码样列,我觉得非常有帮助,现在分享出来大家 ...

  3. 学习python最好的书籍_最好的Python书籍

    学习python最好的书籍 Python is an amazing programming language. It can be applied to almost any programming ...

  4. python 数据科学书籍_您必须在2020年阅读的数据科学书籍

    python 数据科学书籍 "We're entering a new world in which data may be more important than software.&qu ...

  5. python django 动态网页_Django-手撸简易web框架-实现动态网页-wsgiref初识-jinja2初识-python主流web框架对比-00...

    自己动手实现一个简易版本的web框架 在了解python的三大web框架之前,我们先自己动手实现一个. 备注: 这部分重在掌握实现思路,代码不是重点 代码中也有许多细节并未考虑,重在实现思路 手撸一个 ...

  6. python金融量化书籍_超强干货 | Python金融数据量化分析教程+机器学习电子书

    如今Python语言的学习已经上升到了国家战略的层面上.Python语言是人工智能的基础语言,国家相关教育部门对于"人工智能普及"格外重视,不仅将Python列入到小学.中学和高中 ...

  7. Python自动化开发学习的第十一周----WEB框架--Django基础

    WEB框架的本质 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #coding:utf-8imp ...

  8. 自学python的经典书籍_有哪些 Python 经典书籍?

    内容太长,完整内容请访问原文: python 3.7极速入门教程9最佳python中文工具书籍下载 筛选了2年内优秀的python书籍,个别经典的书籍扩展到5年内. python现在的主流版本是3.7 ...

  9. python接口自动化测试书籍_干货丨Python接口测试自动化实战及代码示例:含get、post等方法...

    引言:年初参与到一个后台系统开发的项目中,里面涉及了很多接口,我做为项目组测试人员,需要对这些接口进行测试,一开始使用 postman 工具测试,很是方便.但随着接口数量的增加,不光要执行手动点击测试 ...

最新文章

  1. buffers和cache的区别
  2. java springmvc mybatis mysql
  3. mybatis实现反向工程
  4. MacOS中Elasticsearch的安装「借助Homebrew」
  5. Oracle中通过游标执行带参数的存储过程实现解析CLOB字段内的xml字符串:
  6. 【BZOJ3956】Count,单调栈+ST表维护区间最大值
  7. 知识图谱之WordNet
  8. 知钱俱乐部 php,知钱俱乐部
  9. 全智通A+常见问题汇总解答—A+打印本次派工单,结果显示所派工项目
  10. js splice的三个用法
  11. java开发程序员培训班,成功跳槽阿里!
  12. 【案例分享】某银行用这20件事,实现数字化转型
  13. Java 8 Stream 总结
  14. 《关于组织申报2017年度高新技术企业的通知》
  15. 图神经网络基础--图结构数据
  16. 关于“ROS2 Topic-Statistics-Tutorial编译出错”的思考2
  17. 设备异常状态检测相关内容(一)
  18. php多用户修改头像源码,PHP 针对多用户 实现头像更换
  19. 2017年电气报价软件排名!评分最高的是它
  20. nonebot2聊天机器人插件3:计算器calculator

热门文章

  1. SVM处理月亮、鸢尾花数据集
  2. 基于K-Means的文本聚类算法
  3. 计算机一级考试个人小结作文,考试总结作文
  4. 荐书丨脑电实验的夺命连环问,你敢来么
  5. c#处理引用程序集带有黄色叹号的方法
  6. 模块和包.colorama
  7. 关于watch跟computed的基础用法
  8. 产品设计体会(二三)——用户研究
  9. 抽象语法树 -Abstract Syntax Tree
  10. 初次使用matlab导入txt文件