一、django字段和字段参数介绍

class Book(models.Model):# 如果不写id,会默认一个id,并且自增#primary_key=True  表示该字段是主键,一个表中只能由一个主键# id = models.AutoField(primary_key=True)# varchar类型,长度,# 字段是否可以为空:null=True,可以为空# 默认值:default='未知书名',如果没传,默认是它# 设置索引:db_index=True 表示该字段是辅助索引# 是否唯一:unique=True 表示唯一name=models.CharField(max_length=32,null=True,default='未知书名',db_index=True,unique=True)# float类型# max_digits 最大长度是5  4567.5# decimal_places=2 小数点后两位   23.56     999.99price=models.DecimalField(max_digits=5,decimal_places=2)# DateTimeField年月日时分秒# auto_now=True  修改,默认使用当前时间# auto_now_add=True 新增,设置当前时间publish_date=models.DateTimeField(auto_now=True)publish=models.CharField(max_length=32)

二、单表查询

# 查询名字叫xxx的书from app01 import models
def books(request):# models.Book.objects.create(name='xxx',price=10.34,publish='南京出版社')### book=models.Book(name='yyy',price=11.34,publish='南京出版社')# book.save()# 查询所有res=models.Book.objects.all()print(res)# 查询名字叫xxx的书(是个列表:QuerySet)res = models.Book.objects.filter(name='xxx')res = models.Book.objects.filter(name='xxx')[0]res = models.Book.objects.filter(name='xxx').first()# 查询名字叫xxx的书(就是book对象),如果没有或者由多个,都报错# 查询结果必须有且仅有一个才正常,否则报错res=models.Book.objects.get(name='sss')# print(res.name)return HttpResponse('两本书保存成功')

三、常用字段和非常用字段和参数简介

  常用字段-IntegerField   整数-AutoField-BooleanField-CharField-DateField-DateTimeField-DecimalField(max_digits=5, decimal_places=2)-FileField   上传文件,本质是varchar-ImageField   图片,本质是varchar,继承了FileField-TextField   存大文本-EmailField   本质是varchar非常用字段-BigAutoField-SmallIntegerField   -PositiveSmallIntegerField-PositiveIntegerField-BigIntegerField'AutoField': 'integer AUTO_INCREMENT','BigAutoField': 'bigint AUTO_INCREMENT','BinaryField': 'longblob','BooleanField': 'bool','CharField': 'varchar(%(max_length)s)','CommaSeparatedIntegerField': 'varchar(%(max_length)s)','DateField': 'date','DateTimeField': 'datetime','DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)','DurationField': 'bigint','FileField': 'varchar(%(max_length)s)','FilePathField': 'varchar(%(max_length)s)','FloatField': 'double precision','IntegerField': 'integer','BigIntegerField': 'bigint','IPAddressField': 'char(15)','GenericIPAddressField': 'char(39)','NullBooleanField': 'bool','OneToOneField': 'integer','PositiveIntegerField': 'integer UNSIGNED','PositiveSmallIntegerField': 'smallint UNSIGNED','SlugField': 'varchar(%(max_length)s)','SmallIntegerField': 'smallint','TextField': 'longtext','TimeField': 'time','UUIDField': 'char(32)',常用参数-null-max_length-default-primary_key-unique-db_index-choices:比较常用(后面再说)-blank: django admin里提交数据,限制元数据-必须记住的class Meta:#  数据库中显示的表名db_table = "book"#  联合索引index_together = [("name", "publish"),]#  联合唯一unique_together = (("name", "publish"),)-了解#  admin中显示的表名称verbose_name='图书表'#verbose_name加sverbose_name_plural='图书表'class Book(models.Model):id=models.AutoField(primary_key=True)name=models.CharField(max_length=32)时区相关默认存当前时间,默认存utc时间咱们是东八区,存到数据库中时间差8个小时通过设置,让存的时候,就存东八区时间,在配置文件中publish_date=models.DateTimeField(auto_now_add=True)blank=True 在admin中新增数据,可以为空修改跟数据库有关才需要做迁移publish=models.CharField(max_length=32,null=True,blank=True)class Meta:表名db_table = "book"联合索引index_together = [("name", "publish"),]联合唯一unique_together = (("name", "publish"),)admin中显示的表名称verbose_name='图书表'#verbose_name加sverbose_name_plural='图书表'#  自定义字段
class MyCharField(models.Field):def __init__(self, max_length, *args, **kwargs):self.max_length = max_lengthsuper().__init(max_length=max_length, *args, **kwargs)def db_type(self, connection):return 'char(%s)' % self.max_length

五、打印原生SQL配置

1 配置文件粘贴
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',},}
}

六、查询表记录API

<1> all():                  查询所有结果
<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
<4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
<5> order_by(*field):       对查询结果排序('-id')
<6> reverse():              对查询结果反向排序
<8> count():                返回数据库中匹配查询(QuerySet)的对象数量。
<9> first():                返回第一条记录
<10> last():                返回最后一条记录
<11> exists():              如果QuerySet包含数据,就返回True,否则返回False<12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列models的实例化对象,而是一个可迭代的字典序列<13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列<14> distinct():            从返回结果中剔除重复纪录##  单表api操作# 1 all 查询所有,返回queryset对象,目前先当成列表(像列表)res=models.Book.objects.all()print(res)from django.db.models.query import QuerySetprint(type(res))# 2 filter 过滤 queryset对象的方法res=models.Book.objects.filter(name='红楼梦')print(res)res=models.Book.objects.all().filter(name='红楼梦')print(res)res = models.Book.objects.all().filter(name='红楼梦',publish='东京出版社')print(res)print(type(models.Book.objects))   暂时不用管#  # 3 get  queryset对象的方法res = models.Book.objects.all().get(name='红楼梦')res = models.Book.objects.get(name='红楼梦')res = models.Book.objects.filter().get(name='红楼梦')# 4  exclude  排除 ,返回queryset对象,可以继续链式调用查询名字不是红楼梦的数据res=models.Book.objects.exclude(name='红楼梦')print(res)# 5 order_by  排序(先后,由顺序)  加-表示降序res=models.Book.objects.all().order_by('id')res=models.Book.objects.all().order_by('-id')res=models.Book.objects.all().order_by('name','-id',)res=models.Book.objects.all().order_by('-id','name')print(res)# 6 reverse 反向 ,必须结合order_by使用,对结果进行反转等同于 ('-i')res = models.Book.objects.exclude(name='红楼梦').order_by('id')res = models.Book.objects.exclude(name='红楼梦').order_by('id').reverse()print(res)# 7 count  统计条数res=models.Book.objects.exclude(name='红楼梦').count()res=models.Book.objects.all().count()print(res)# 9 first  返回结果不再是queryset对象了res = models.Book.objects.exclude(name='红楼梦').first()print(res)# 10 last  返回结果不再是queryset对象了res = models.Book.objects.exclude(name='红楼梦').last()print(res)# 11  exists() 判断结果有没有值 返回结果不再是queryset对象了res = models.Book.objects.exclude(name='红楼梦').exists()print(res)res = models.Book.objects.filter(name='红楼梦dasf').exists()print(res)# 12 values  select name from book; 指定只查某几个字段res = models.Book.objects.all().values('name','publish')res = models.Book.objects.all().values('name','publish').first()print(type(res))# 13 values_listres = models.Book.objects.all().values_list('name','publish').first()print(res)print(type(res))# 14 distinct 对结果进行去重res = models.Book.objects.all().values('name','publish').distinct()res = models.Book.objects.all().values('name').distinct()print(res)res.query()  # 查看内部封装的sql语句,前提是对象时queryset对象

七、基于双下划线的模糊查询

  # 1  价格在[100,200,300]这个范围内
Book.objects.filter(price__in=[100,200,300])# 2 大于,小于,大于等于,小于等于
Book.objects.filter(price__gt=100)
Book.objects.filter(price__lt=100)
Book.objects.filter(price__gte=100)
Book.objects.filter(price__lte=100)# 3 范围
Book.objects.filter(price__range=[100,200])# 4 包含
Book.objects.filter(title__contains="python")# 5 忽略大小写包含
Book.objects.filter(title__icontains="python")# 6 以xx开头
Book.objects.filter(title__startswith="py")# 7 时间类型,年份是2012年的
Book.objects.filter(pub_date__year=2012)

八、删除、修改表记录

删除的两种方式第一种:queryset的delete方法res=models.Book.objects.all().delete()print(res)第二种:对象自己的delete方法book = models.Book.objects.all().filter(name='红楼梦').first()print(type(book))res=book.delete()
    修改记录第一种:queryset的update方法res=models.Book.objects.filter(publish='东京').update(name='红楼梦1')print(res)第二种:对象自己的book = models.Book.objects.filter(name='xxx').last()book.name='红楼梦1'book.save()

九、在Django中使用测试模式

# 新建一个test.py
import os
if __name__ == '__main__':1  引入django配置文件os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day67.settings')2 让djagno启动import djangodjango.setup()3 使用表模型from app01 import modelsmodels.Book.objects.create(name='测试书籍',publish='xx出版社')

十、时区和国际化

setting.py中
1 后台管理汉语问题LANGUAGE_CODE = 'zh-hans'    管理后台看到的就是中文
2 时区问题(使用东八区)TIME_ZONE = 'Asia/Shanghai'USE_TZ = False

十一、Django后台管理账号的创建

0 管理后台是django提供的可以快速对表进行增删查改操作1 创建一个后台管理账号python3 manage.py createsuperuser输入用户名输入邮箱(可以不填,敲回车)输入密码确认密码超级用户创建出来了,可以登录管理后台了
2 admin中表中一行一行的数据显示我们定制的样子(************)重写模型类的__str__方法3 blank参数作用
1 需要把book表注册到admin中在app下的admin.py中写from app01 import models把book表注册,管理后台就能看到了admin.site.register(models.Book)
2 可以快速的对book表进行增删查改操作   3、blank=True  # 在admin中可以允许插入空值

十二、多表创建之模型创建

1 图书表:book,作者表:author,作者详情表:authordetail,出版社表:publish,(第三张中间表)
2 作者跟作者详情:是一对一,关联字段写在哪一方都可以
3 图书跟出版社:是一对多,一对多关系一旦确立,关联字段写在多的一方
4 图书和作者:是多对多,多对多的关系需要建立第三张表(可以自动生成)5 models.py中把关系建立出来
from django.db import models
### django:
# Create your models here.
class Publish(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)addr = models.CharField(max_length=64)phone = models.CharField(max_length=64)email = models.EmailField()class AuthorDetail(models.Model):id = models.AutoField(primary_key=True)sex = models.SmallIntegerField()addr = models.CharField(max_length=64)phone = models.BigIntegerField()class Author(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)age = models.SmallIntegerField()# 一对一的本质是  ForeignKey+uniqueauthor_detail=models.OneToOneField(to='AuthorDetail',to_field='id')# author_detail=models.ForeignKey(to='AuthorDetail',to_field='id',unique=True)class Book(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)price = models.DecimalField(max_digits=6, decimal_places=2)publish_date = models.DateTimeField(auto_now_add=True)# to='Publish'跟Publish表做关联(ForeignKey,一对多)# to_field='id'跟哪个字段做关联# publish=models.CharField(max_length=32)# publish=models.ForeignKey(to='Publish',to_field='id')  # 写,跟id做关联# publish = models.ForeignKey(to='Publish')  # 不写,默认跟主键做关联publish = models.ForeignKey(to=Publish)  # 自动创建出第三张表(这句话会自动创建第三章表)# authors在数据库中不存在该字段,没有to_field# 默认情况:第三张表有id字段,当前Book表的id和Author表的id字段authors=models.ManyToManyField(to='Author')    6 同步到mysql数据库-配置文件-pymysql.install_as_mysqldb()-公司可以用过的mysqlclient-两条迁移命令:makemigrationsmigrate

十三、一对多添加记录

  # 新增红楼梦图书
publish=models.Publish.objects.create(name='北京出版社',addr='北京',phone='0536-12345678',email='邮箱地址')# 新增红楼梦图书
book=models.Book.objects.create(name='红楼梦',price='23.45',publish=publish)# publish=对象# book=models.Book.objects.create(name='西游记',price='23.55',publish_id=1)# publish_id=数字# 新增西游记
book=models.Book.objects.create(name='西游记',price='23.55',publish_id=publish.id)# publish_id=数字# 总结:1 email可以不传email,本质就是varchar(admin中会判断)2 新增图书一段多字段的创建:-publish=publish-publish_id=publish.id3 写在表模型中的publish字段,到数据库中会变成publish_id(ForeignKey)4 查到book对象以后-book.publish     对象-book.publish_id  id号,数字

十四、 多对多添加记录,修改,删除

1 自动创建的表,表模型就拿不到,book.authors代指表模型,无法直接在创建书的时候直接创建# 多对多,作者和书# 给西游记这本书新增两个作者wu和 xi# 去到西游记这本书book=models.Book.objects.get(name='西游记')wu=models.Author.objects.get(id=2)xi=models.Author.objects.get(id=3)# 代指中间表book.authorsbook.authors.add(2,3) # 新增作者,通过id新增# # book.authors.add(wu, xi) # 新增作者,通过对象新增# book.authors.add(2, xi) # 新增作者,通过对象新增# 西游记删除一个作者book = models.Book.objects.get(name='西游记')book.authors.remove(2)xi = models.Author.objects.get(id=3)book.authors.remove( xi)  # 已经取到了作者对象# clear 清空所有作者book = models.Book.objects.get(name='西游记')book.authors.add(2, 3)book.authors.clear()# set 先清空,再add,前提是不存在的作者,必须放在列表里book.authors.set([4, ])# add ,remove,set clear

十五、基于对象的跨表查询(正向反向)

# 跨表查询有两种方式-基于对象的跨表查询:子查询-基于双下划线的跨表查询:关联查询,连表查询# 基于对象的跨表查询-查询主键为1的书籍的出版社所在的城市# 基于对象的跨表查询(子查询)# 一对多# 查询主键为1的书籍的出版社所在的城市book=models.Book.objects.get(id=1) # 第一次查询book=models.Book.objects.filter(id=1).first()publish=book.publish  # 内部又执行了一次查询,根据publish_id查询publishprint(publish.addr)# 北京出版社出版的所有书籍publish=models.Publish.objects.get(name='北京出版社')  # 第一次查询了出版社books=publish.book_set.all()    # 表名小写_set     # 第二次,根据出版社id,查询所有书print(books)"""正向查询:book表内有publish字段 直接对象.字段名反向查询:publish表内没有book字段,出版社对象.表名小写_set.all()"""### 一对一# 查询所有住址在山东的作者的姓名# 反向查询:author_detail没有author字段,author_detail.表名小写author_detail=models.AuthorDetail.objects.filter(addr__contains='山东').first()# # 反向print(author_detail.author.name)# 查询 xi作者的地址# 正向author=models.Author.objects.get(name=' xi')print(author.author_detail.addr)# 多对多关系查询#红楼梦所有作者的名字以及手机号book=models.Book.objects.get(name='红楼梦')# # 正向authors=book.authors.all()for author in authors:print(author.name)print(author.author_detail.phone)# 反向 查询 xi出过的所有书籍的名字xi=models.Author.objects.get(name=' xi')books=egon.book_set.all()for book in books:print(book.name)

十六、基于双下划线的跨表查询

# 连表查询基于对象的跨表查询,先查对象,通过对象再去查另一个对象(正向:字段名,反向:表名小写/表名小写_set.all())# 地址为山东的作者写的所有书author_detail=models.AuthorDetail.objects.get(addr='山东')author=author_detail.authorbooks=author.book_set.all()print(books[0].name)--(作业)地址为山东的作者写的所有书的出版社名字author_detail = models.AuthorDetail.objects.get(addr = '山东')author=author_detail.authorbooks = author.book_set.all()for book in books:publish = book.publishprint(publish.name)### 基于双下划线的跨表查之  一对多正向:字段名反向:表名小写filter,values,values_list(写 __ 跨表)# 练习:  查询北京出版社出版过的所有书籍的名字与价格(一对多)# SELECT `app01_book`.`name`, `app01_book`.`price` FROM `app01_publish` LEFT OUTER JOIN `app01_book` ON (`app01_publish`.`id` = `app01_book`.`publish_id`) WHERE `app01_publish`.`name` = '北京出版社' ;res=models.Publish.objects.filter(name='北京出版社').values('book__name','book__price')print(res)#SELECT `app01_book`.`name`, `app01_book`.`price` FROM `app01_book` INNER JOIN `app01_publish` ON (`app01_book`.`publish_id` = `app01_publish`.`id`) WHERE `app01_publish`.`name` = '北京出版社';res=models.Book.objects.filter(publish__name='北京出版社').values('name','price')print(res)## 多对多# 练习: 查询 xi出过的所有书籍的名字,价格(多对多)#反向res=models.Author.objects.filter(name=' xi').values('book__name','book__price')print(res)# 正向res=models.Book.objects.filter(authors__name=' xi').values('name','price')print(res)#查询 xi的手机号res=models.Author.objects.filter(name=' xi').values('author_detail__phone')print(res)res=models.AuthorDetail.objects.filter(author__name=' xi').values('phone')print(res)# 连续跨表#查询北京出版社出版过的所有书籍的名字以及作者的姓名res=models.Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name')print(res)res=models.Book.objects.filter(publish__name='北京出版社').values('name','authors__name')print(res)res=models.Author.objects.filter(book__publish__name='北京出版社').values('book__name','name')print(res)# 手机号以189开头的作者出版过的所有  书籍名称  以及   出版社名称res=models.AuthorDetail.objects.filter(phone__startswith='189').values('author__book__name','author__book__publish__name')print(res)res=models.Author.objects.filter(author_detail__phone__startswith='189').values('book__name','book__publish__name')print(res)

十七、安装模块相关

pip3 install django
# 本质是去https://pypi.python.org/simple,搜这个模块,会根据你的平台下载在一个安装包(windows平台是whl),下载完,再安装# pip安装失败的情况
# 我们可以绕过它,有了whl文件以后,自己装
# https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
pip3 install django.whl   # 官方库没有上传到pypi,官方也不给制作whl文件
#如何安装  包 (setup.py)
到达安装目录,setup.py所在的目录
python setup.py build
python setup.py install# 配置清华源,豆瓣源,本质是
豆瓣源会把pypi,包拉到自己的服务器上,以后你再下,去它的服务器上下,所以速度快

十八、Django版本不同在创建外键是的区别

7 --2.x版本的django-外键字段必须加  参数:on_delete-1.x版本不需要,默认就是级联删除-假设,删除出版社,该出版社出版的所有图书也都删除,on_delete=models.CASCADE删除出版社,该出版社出版的图书不删除,设置为空on_delete=models.SET_NULL,null=True删除出版社,该出版社出版的图书不删除,设置为默认on_delete=models.SET_DEFAULT,default=0

十九、聚合查询

###########1 聚合查询(聚合函数:最大,最小,和,平均,总个数)
"""D:\Djangozuoye\zuoye1014"""django项目路径from django.db.models import Avg,Max,Min,Count,Sum
#1 计算所有图书的平均价格
aggregate结束,已经不是queryset对象了
book=models.Book.objects.all().aggregate(Avg('price')){'price__avg': 57.0}
# 起别名
book=models.Book.objects.all().aggregate(avg=Avg('price')){'avg': 57.0}
#2 计算总图书数
book = models.Book.objects.all().aggregate(count=Count('id')){'count': 10}
# 3 计算最低价格的图书
book = models.Book.objects.all().aggregate(min=Min('price')){'min': Decimal('6.00')}
# 4 计算最大价格图书
book = models.Book.objects.all().aggregate(max=Max('price')){'max': Decimal('120.00')}print(book)

二十、分组查询

 ####2  分组查询'''查询每一个部门名称以及对应的员工数book:id  name   price      publish1   金品   11.2        12   西游   14.2        23   东游   16.2        24   北邮   19.2        3'''# 示例一:查询每一个出版社id,以及出书平均价格select publish_id,avg(price) from app01_book group by publish_id;SELECT publish_id,AVG(price),GROUP_CONCAT(id) FROM app01_book GROUP BY publish_id;# annotate#  annotate() 内写聚合函数#  values在前表示group by的字段#  values在后表示取某几个字段#  filter在前表示where#  filter在后表示havingfrom django.db.models import Avg, Count, Max, Min# 查询每个出版社出版图书的平均价格和出版社名称
ret=models.Book.objects.values('publish_id').annotate(avg=Avg('price')).values('publish_name','avg')print(ret)<QuerySet [{'publish__name': '沙河出版社', 'avg': 46.25}, {'publish__name': '人民出版社', 'avg': 52.333333}, {'publish__name': '瑶池出版社', 'avg': 76.0}]># 查询出版社id大于1的出版社id,以及出书平均价格select publish_id,avg(price) from app01_book where publish_id>1 group by publish_id;ret = models.Publish.objects.filter(id__gt=1).annotate(avg=Avg('book__price')).values('id', 'avg')   ret = models.Book.objects.filter(publish_id__gt=1).values('publish__id').annotate(avg=Avg('price')).values('publish__id', 'avg')   ret=models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg=Avg('price')).values('publish_id','avg')print(ret)<QuerySet [{'publish__id': 2, 'avg': 52.333333}, {'publish__id': 3, 'avg': 76.0}]># 查询出版社id大于1的出版社id,以及出书平均价格大于60的select publish_id,avg(price)as avg from app01_book where publish_id>1 group by publish_id HAVING avg>60;ret = models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg=Avg('price')).filter(avg__gt=60).values('publish_id', 'avg')print(ret)<QuerySet [{'publish__id': 3, 'avg': 76.0}]>## 查询每一个出版社出版的书籍个数# pk 代指主键ret=models.Book.objects.get(pk=1)print(ret.name)ret=models.Publish.objects.values('pk').annotate(count=Count('book__id')).values('name','count')print(ret)<QuerySet [{'name': '沙河出版社', 'count': 4}, {'name': '人民出版社', 'count': 3}, {'name': '瑶池出版社', 'count': 3}]># 如果没有指定group by的字段,默认就用基表(Publish)主键字段作为group by的字段ret=models.Publish.objects.annotate(count=Count('book__id')).values('name','count')print(ret)<QuerySet [{'name': '沙河出版社', 'count': 4}, {'name': '人民出版社', 'count': 3}, {'name': '瑶池出版社', 'count': 3}]># 另一种方式实现ret=models.Book.objects.values('publish_id').annotate(count=Count('id')).values('publish__name','count')print(ret)<QuerySet [{'name': '沙河出版社', 'count': 4}, {'name': '人民出版社', 'count': 3}, {'name': '瑶池出版社', 'count': 3}]>#查询每个作者的名字,以及出版过书籍的最高价格(建议使用分组的表作为基表)# 如果不用分组的表作为基表,数据不完整可能会出现问题ret=models.Author.objects.values('pk').annotate(max=Max('book__price')).values('name','max')ret = models.Author.objects.annotate(max=Max('book__price')).values('name', 'max')ret= models.Book.objects.values('authors__id').annotate(max=Max('price')).values('authors__name','max')print(ret)<QuerySet [{'name': '大', 'max': Decimal('120.00')}, {'name': '中', 'max': Decimal('120.00')}, {'name': '小', 'max': Decimal('120.00')}]>#查询每一个书籍的名称,以及对应的作者个数ret=models.Book.objects.values('pk').annotate(count=Count('author__id')).values('name','count')ret=models.Book.objects.annotate(count=Count('author__id')).values('name','count')ret=models.Author.objects.values('book__id').annotate(count=Count('id')).values('book__name','count')#print(ret)<QuerySet [{'name': '红0', 'count': 3}, {'name': '红楼梦1', 'count': 2}, {'name': '红楼梦', 'count': 2}, {'name': '红楼梦', 'count': 2}, {'name': '红楼梦', 'count': 1}, {'name': '红楼梦', 'count': 1}, {'name': '红6', 'count': 1}, {'name': '红7', 'count': 1}, {'name': '红8', 'count': 1}, {'name': '红9', 'count': 1}]>#统计不止一个作者的图书ret=models.Book.objects.values('pk').annotate(count=Count('authors__id')).filter(count__gt=1).values('name','count')ret = models.Author.objects.values('book__id').annotate(count=Count('id')).filter(count__gt=1).values('book__name', 'count')print(ret)<QuerySet [{'name': '红0', 'count': 3}, {'name': '红楼梦1', 'count': 2}, {'name': '红楼梦', 'count': 2}, {'name': '红楼梦', 'count': 2}]># 上述结果可以去重res = models.Book.objects.values('pk').annotate(count=Count('author')).filter(count__gt=1).values('name', 'count').distinct()<QuerySet [{'name': '红0', 'count': 3}, {'name': '红楼梦1', 'count': 2}, {'name': '红楼梦', 'count': 2}]># 统计价格数大于10元,作者的图书ret = models.Book.objects.values('pk').filter(price__gt=10).annotate(count=Count('authors__id')).values('name','count')print(ret)#统计价格数大于10元,作者个数大于1的图书ret = models.Book.objects.values('pk').filter(price__gt=10).annotate(count=Count('authors__id')).filter(count__gt=1).values('name','count')print(ret)

二十一、F与Q查询

 # F查询:取出数据库的某个字段的值# res = models.Book.objects.values(F('read_num'))  报错res = models.Book.objects.values('name', read=F('read_num'))<QuerySet [{'name': '红0', 'read': 1}, {'name': '红楼梦1', 'read': 534}, {'name': '红d楼梦', 'read': 534}, {'name': '红楼梦', 'read': 5344}, {'name': '红楼梦', 'read': 7675}, {'name': '红楼梦', 'read': 3}, {'name': '红6', 'read': 346}, {'name': '红7', 'read': 54}, {'name': '红8', 'read': 546}, {'name': '红9', 'read': 657}]># 把read_num都加1from django.db.models import Fret=models.Book.objects.all().update(read_num=F('read_num')+1)print(ret)(0.056) UPDATE `app01_book` SET `read_num` = (`app01_book`.`read_num` + 1); args=(1,)10#查询评论数大于阅读数的书籍ret=models.Book.objects.all().filter(speak_num__gt=F('read_num')).values('name')<QuerySet [{'name': '红0'}, {'name': '红楼梦1'}, {'name': '红楼梦'}, {'name': '红6'}, {'name': '红7'}]>    ## 查询评论数大于阅读数2倍的书籍ret=models.Book.objects.filter(speak_num__gt=F('read_num')*2)print(ret)<QuerySet [{'name': '红0'}, {'name': '红楼梦1'}, {'name': '红楼梦'}, {'name': '红6'}, {'name': '红7'}]>
# Q查询:制造  与或非的条件# Q查询:制造  与或非的条件# 查询名字叫红楼梦或者价格大于100的书from django.db.models import Qres = models.Book.objects.filter(Q(name='红楼梦') | Q(price__gt=100)).values('name', 'price')<QuerySet [{'name': '红楼梦', 'price': Decimal('100.00')}, {'name': '红楼梦', 'price': Decimal('120.00')}, {'name': '红楼梦', 'price': Decimal('100.00')}, {'name': '红楼梦', 'price': Decimal('120.00')}]># 查询名字叫红楼梦并且价格大于100的书res = models.Book.objects.filter(Q(name__contains='红') & Q(price__lt=100)).values('name', 'price')print(res)<QuerySet [{'name': '红0', 'price': Decimal('50.00')}, {'name': '红楼梦1', 'price': Decimal('50.00')}, {'name': '红6', 'price': Decimal('6.00')}, {'name': '红7', 'price': Decimal('7.00')}, {'name': '红8', 'price': Decimal('8.00')}, {'name': '红9', 'price': Decimal('9.00')}]># 查询名字不为红楼梦的书res = models.Book.objects.filter(~Q(name='红楼梦')).values('name')print(res)<QuerySet [{'name': '红0'}, {'name': '红楼梦1'}, {'name': '红6'}, {'name': '红7'}, {'name': '红8'}, {'name': '红9'}]># Q可以嵌套res = models.Book.objects.filter((Q(name='红楼梦') & Q(price=100)) | Q(id__lt=2)).values('id','name', 'price')print(ret)<QuerySet [{'id': 1, 'name': '红0', 'price': Decimal('50.00')}, {'id': 3, 'name': '红楼梦', 'price': Decimal('100.00')}, {'id': 5, 'name': '红楼梦', 'price': Decimal('100.00')}]>

二十二、原生SQL

    # 原生sql(有些sql用orm写不出来)# 两种方案# 第一种:用的比较少from django.db import connection#cursor = connection.cursor()#cursor.execute('select * from app01_book where id < %s', [2])## # row = cursor.fetchone()row = cursor.fetchall()print(row)((1, '红0', Decimal('50.00'), datetime.datetime(2017, 10, 14, 18, 32, 48, 720483), 1, 2, 3465),)# 第二种,用的多books=models.Book.objects.raw('select * from app01_book where id <2')print(books)#RawQuerySet对象for book in books:print(book.id)print(book.name)1
红0books=models.Book.objects.raw('select * from app01_publish where id < 3')for book in books:print(book.__dict__)print(book.id)print(book.name)print(book.addr)print(book.price){'_state': <django.db.models.base.ModelState object at 0x0000000003FF7190>, 'id': 1, 'name': '沙河出版社', 'addr': '北京', 'phone': '0526-123'}
1
沙河出版社
北京
50.00
{'_state': <django.db.models.base.ModelState object at 0x0000000003FF72B0>, 'id': 2, 'name': '人民出版社', 'addr': '上海', 'phone': '0527-456'}
2
人民出版社
上海
50.00(0.012) select * from app01_publish where id < 3; args=()
(0.000) SELECT VERSION(); args=None
(0.000) SELECT `app01_book`.`id`, `app01_book`.`price` FROM `app01_book` WHERE `app01_book`.`id` = 1; args=(1,)
(0.009) SELECT `app01_book`.`id`, `app01_book`.`price` FROM `app01_book` WHERE `app01_book`.`id` = 2; args=(2,)进程已结束,退出代码 0authors = models.Author.objects.raw('SELECT app01_author.id,app01_author.name,app01_authordetail.sex FROM app01_author JOIN app01_authordetail ON app01_author.author_detail_id = app01_authordetail.id WHERE app01_authordetail.sex = 1')for author in authors:print(author.name)print(author.__dict__)

二十三、defer和only

    # defer和only(查询优化相关)# 但是只能使用only指定的字段books = models.Book.objects.all().only('name')# books = models.Book.objects.only('name')book = books.first()  # 取第一个值,也支持索引取值print(book.name)print(book.price)  # 能出来,但是会再次去数据库查询
红0
50.00(0.014) SELECT `app01_book`.`id`, `app01_book`.`name` FROM `app01_book` ORDER BY `app01_book`.`id` ASC LIMIT 1; args=()
(0.001) SELECT VERSION(); args=None
(0.001) SELECT `app01_book`.`id`, `app01_book`.`price` FROM `app01_book` WHERE `app01_book`.`id` = 1; args=(1,)# 可以使用defer指定之外的字段,指定的字段使用时需要再次查询,和only相反books = models.Book.objects.defer('name')book = books.first()print(book.name)  # 查询改字段,会再去数据库查询print(book.price)print(book.id)print(book.read_num)print(book.speak_num)(0.075) SELECT `app01_book`.`id`, `app01_book`.`price`, `app01_book`.`publish_date`, `app01_book`.`publish_id`, `app01_book`.`read_num`, `app01_book`.`speak_num` FROM `app01_book` ORDER BY `app01_book`.`id` ASC LIMIT 1; args=()(0.001) SELECT VERSION(); args=None(0.002) SELECT `app01_book`.`id`, `app01_book`.`name` FROM `app01_book` WHERE `app01_book`.`id` = 1; args=(1,)红0
50.00
1
2
3465进程已结束,退出代码 0

二十四、事务的开启

# 事物:ACID,事物的隔离级别(搜),锁, 行级锁,表级锁# djanog orm中使用事物:原子性操作,要么都成功,要么都失败# 新增一个作者详情,新增一个作者# 事物的三个层面# 1 局部使用from django.db import transactionwith transaction.atomic(): # 都在事物中,要么都成功,要么都失败author_detail=models.AuthorDetail.objects.create(addr='瑶池',phone='123',sex=1)# raise Exception('抛了异常')author=models.Author.objects.create(name='璐璐',age=19,author_detail=author_detail)# 2 视图函数装饰器,这视图函数的执行,将会在一个事务中@transaction.atomicdef index(request):return HttpResponse('ok')# 3 整个http请求,在事物中,在setting.py中配置(不推荐!!!!!!!!!!!!!)'''DATABASES = {'default': {...'PORT': 3306,'ATOMIC_REQUEST': True,}}''''ATOMIC_REQUEST': True,设置为True,整个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败)。1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

Django中ORM的具体使用,超全超长超好懂相关推荐

  1. django 模板mysql_59 Django基础三件套 , 模板{{}}语言 , 程序连mysql Django项目app Django中ORM的使用...

    主要内容:https://www.cnblogs.com/liwenzhou/p/8688919.html 1 form表单中提交数据的三要素 a : form标签必须要有action和method的 ...

  2. Django 中ORM 的使用

    一:Django 中 orm 的使用 1:手动新建一个数据库 2 :告诉Django连接哪个数据库 settings.py里配置数据库连接信息: #数据库相关的配置项 DATABASES ={'def ...

  3. 史上最全的Linux常用——目录和文件管理命令——收藏这一篇就够了!(超全,超详细)

    史上最全的Linux常用--目录和文件管理命令--收藏这一篇就够了!(超全,超详细) Linux目录结构 命令 查看文件内容:-cat 查看文件内容:-more 查看文件内容:-less 查看文件内容 ...

  4. 超全、超详的Spring Boot配置讲解笔记

    超全.超详的Spring Boot配置讲解笔记 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些默认配置进行修改. application.prop ...

  5. 高德地图刷新当前位置_再也不怕找错!高德地图更新1号线地铁出入口信息啦!超全!超详细!...

    原标题:再也不怕找错!高德地图更新1号线地铁出入口信息啦!超全!超详细! 为了方便市民乘坐地铁 济南轨道交通集团联合高德地图 将1号线全线车站位置和出入口编号 落在了地图上 是不是很贴心? 以后再也不 ...

  6. 西游之路——python全栈——django中orm的使用(1)

    目录 首先推荐两篇文章:Django之ORM操作,http://www.cnblogs.com/yuanchenqi/articles/6083427.html十分全面. 另外和python---OR ...

  7. Django中ORM操作

    一.ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. ​ 简单的说,ORM是通过使用描述对象 ...

  8. Django中ORM之或语句查询

    比如数据库表中有显示器1和显示器2,那么如何在django中模糊查询出显示器1和显示器2呢 首先导入模块 from django.db.models import Qclass GetDisplay( ...

  9. Django中ORM中queryset方法详解

    1.queryset的含义 queryset是查询集,就是传到服务器上的url里面的查询内容.Django会对查询返回的结果集QuerySet进行缓存,这是为了提高查询效率.也就是说,在你创建一个Qu ...

最新文章

  1. linux设备驱动第一篇:设备驱动程序简介
  2. 单行文本溢出显示省略号,单行文本溢出显示省略号
  3. JavaScript快速入门(六)——DOM
  4. boost::core模块实现分配器指针
  5. angular element()
  6. CentOS 7上快速安装saltstack
  7. DevExpress 隐藏Ribbon中barbuttonItem的SuperTip(2)
  8. 批处理只执行第一句,其他的不被执行,怎么办?
  9. word如何设置页眉横线的磅数
  10. android开发中TabHost使用方法
  11. 如何用matlab画一个球
  12. android底层优化什么意思,华为所谓的“优化”到底是什么意思 看完这段你就明白...
  13. linux内核不能识别u盘分区,一种在Linux内核中识别特定USB大容量存储设备的方法及系统与流程...
  14. P1598 垂直柱状图
  15. Python学习笔记之 中英文文本情感分析
  16. 区块链技术在网络安全上的应用
  17. 阿里云安全增强计算型c6t云服务器参数详解
  18. ​田溯宁投的天润云上市:市值22亿港元 年利润下降75%
  19. 基于C#平台下利用POP3和SMTP协议的邮件归档系统
  20. matlab数值积分的计算

热门文章

  1. postman快速使用
  2. 智能化CSS检测法,好优化拒绝冗杂代码
  3. “问渠哪得清如许?为有源头活水来” – 提高技术源头数据的质量成为技术信息化热点
  4. 读书笔记-深度学习推荐系统4-推荐与embedding
  5. 3步了解APP渠道应该怎样建设评估体系(上)
  6. bootstrap-table固定表的高度
  7. 搭建云平台(一) 云平台基础服务部署
  8. 140.210.28.29扬州BGP高防服务器
  9. 申请软著材料提交注意事项
  10. HDU 1560 sequence