django(5)

django(5),第1张

概述复习settar和getattr getattr(对象,属性,默认值)对象中取出属性的值setattr(对象,属性,属性的值)为对象添加新的属性 CBV的源码截图 django settings源码 importilb模块 第二节课 一、双下划线查询 1.1打印orm内部sql语句的两种方法? 1.如果是queryset对象 那么可以点query直接查看该queryset的内部sql语句# 不

复习settar和getattr

getattr(对象,属性,默认值)对象中取出属性的值setattr(对象,属性,属性的值)为对象添加新的属性
CBV的源码截图

django settings源码

importilb模块

第二节课

一、双下划线查询

1.1打印orm内部SQL语句的两种方法?

1.如果是queryset对象 那么可以点query直接查看该queryset的内部SQL语句# 不是2.在django项目的配置文件中 配置一下参数即可实现所有的orm在查询的时候自动打印对应的SQL语句

django配置文件(settings)

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

修改数据库的两行代码:

makemigrationsmigrate

在django中你可以写一个单独测试某一个py文件的测试脚本不需要再频繁的走web请求

在根目录下建立test.pyimport osimport sysif __name__ == "__main__":    # django在启动的时候 就会往全局的大字典中设置一个键值对  值是暴露给用户的配置文件的路径字符串    os.environ.setdefault("DJANGO_SETTINGS_MODulE","day54.settings")    import django    django.setup()    from app01 import models

liMIT的作用:

这个是为了避免数据库的压力,防止数据特别巨大

使用该,来复习原生SQL语句!

双下查询:

总结:双下查询等于是封装了原生SQL语句,变成其他另一个语法。简单易用!值得推荐

"""神奇的双下滑查询"""# 查询价格大于200的书籍# res = models.Book.objects.filter(price__gt=200) #查询结果不包括200!# print(res)# 查询价格小于200的书籍# res = models.Book.objects.filter(price__lt=200)# print(res)# 查询价格大于等于200.22的书籍# res = models.Book.objects.filter(price__gte=200)# print(res)# 查询价格小于等于200.22的书籍# res = models.Book.objects.filter(price__lte=200.22)# print(res)# 查询价格要么是200,要么是300,要么是666.66# res = models.Book.objects.filter(price__in=[200,300,666.66])# print(res)# 查询价格在200到800之间的# res = models.Book.objects.filter(price__range=(200,800))  # 两边都包含# print(res)# 查询书籍名字中包含p的"""在打印的原生SQL语句 模糊匹配出现        like            %            _    """#拿到价格里包含数字0的注意!!只在@R_404_5605@生效注意!!只在@R_404_5605@生效注意!!只在@R_404_5605@生效res = models.Book.objects.filter(price__contains=0) # 仅仅只能拿小写pres = models.Book.objects.filter(Title__icontains='p')  # 忽略大小写#print(res)# 查询书籍是以三开头的# res = models.Book.objects.filter(Title__startswith='三')# res1 = models.Book.objects.filter(Title__endswith='p')# print(res)# print(res1)# 查询出版日期是2017的年(******)# res = models.Book.objects.filter(create_time__year='2017')# print(res)
图书管理系统表的创建

数据库切换为@R_404_5605@的 *** 作步骤:

1.新建一个数据库2.settings中修改ATABASES的数据3.init文件写入两句话:import py@[email protected]_as_@R_404_5605@db()

更换 *** 作:1

2

现在models创建三张表,并设置好外键关系,数据库生效的两条命令是?!

pycharm中makemigrations产生表记录migrate保存到数据库

现在录入数据库数据

tests脚本,就不用再浏览器点击了。这是针对某一py文件的测试代码

二、多表 *** 作 外键字段的增删改查 2.1一对多的字段的增删改查

? 2.1.1增create():

publish参数有两个选项:1publish_ID传数字 ;2publish直接传出版社对象

# **一对多的字段的增删改查**# 增:# 1.publish_ID传数字models.Book.objects.create(Title='三国义',price=189.99,publish_ID=1)# 2.publish直接传出版社对象publish_obj = models.Publish.objects.filter(pk=2).first()models.Book.objects.create(Title='梦',price=999.99,publish=publish_obj)

? 2.1.2改update()

同样,外键字段也可以传两种:1.传数字的;2.传对象的

# 改update()# 1.传数字的res= models.Book.objects.filter(pk=1).update(publish_ID=3)print(res)# 2.传对象的publish_obj = models.Publish.objects.filter(pk=2).first()print(publish_obj)models.Book.objects.filter(pk=1).update(publish=publish_obj)# 删models.Publish.objects.filter(pk=2).delete()  # 默认都是级联更新 级联删除

2.2多对多字段的增删改查

add()
set()
remove()
上面三个都支持传数字 或者对象 并且可以传多个 但是set需要传可迭代对象

clear()
clear括号内不需要传任何参数

增add()# 要给主键为1的书籍添加两个作者# book_obj = models.Book.objects.filter(pk=1).first()# print(book_obj.authors)  # 对象点击多对多虚拟字段 会直接跨到多对多的第三张表#支持同时添加多个# book_obj.authors.add(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()是给书籍添加作者  括号内既可以传数字也可以传对象并且支持一次性传多个  逗号隔开即可"""改set([])# 将主键为1的书籍对象 作者修改为2,3# book_obj = models.Book.objects.filter(pk=1).first()# book_obj.authors.set([2,])# book_obj.authors.set([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.set([author_obj,])# book_obj.authors.set([author_obj,author_obj1,author_obj2])"""    set()括号内 需要传一个可迭代对象     可迭代对象中 可以是多个数字组合    也可以是多个对象组合    但是不要混着用!!!    """删1.remove()# 一个一个删2.clear() # 清空所有# book_obj = models.Book.objects.filter(pk=1).first()# # book_obj.authors.remove(3)# book_obj.authors.remove(1,2)# 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.remove(author_obj)# book_obj.authors.remove(author_obj1,author_obj2)"""    remove()括号内既可以传数字 也可以传对象     并且支持传对个 逗号隔开即可    """# 将某本书跟作者的关系全部清空# book_obj = models.Book.objects.filter(pk=1).first()# book_obj.authors.clear()  # 清空当前书籍与作者的所有关系"""add()set()remove()上面三个都支持传数字 或者对象 并且可以传多个 但是set需要传可迭代对象clear()clear括号内不需要传任何参数"""

跨表查询(重点)

诀窍:正向查询按外键字段,反向查询按表名小写

正向与反向的概念(******)诀窍:正向查询按外键字段,反向查询按表名小写1基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)2基于双下划綫的跨表查询(连表 *** 作)        left join        inner join        right join        union    # 一对一    # 正向:author---关联字段在author表里--->authordetail     按字段    # 反向:authordetail---关联字段在author表里--->author     按表名小写          # 一对多    # 正向:book---关联字段在book表里--->publish      按字段    # 反向:publish---关联字段在book表里--->book      按表名小写_set.all() 因为一个出版社对应着多个图书        # 多对多    # 正向:book---关联字段在book表里--->author       按字段    # 反向:author---关联字段在book表里--->book       按表名小写_set.all() 因为一个作者对应着多个图书            一、基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)        强调:在书写orm语句的时候 跟写SQL语句一样     不要尝试着 一次性写完  应该做到写一点看一点再一点        # 1.查询书籍ID是1 的出版社名称    # book_obj = models.Book.objects.filter(pk=1).first()    # print(book_obj.publish.name)    # print(book_obj.publish.addr)    book_obj.publish。现在就跨表了,现在就可以.publish的字段了。比如:book_obj.publish.name            # 2.查询书籍ID是2 的作者姓名    # book_obj = models.Book.objects.filter(pk=2).first()    book_obj.authors:app01.Author.None。多对多的关系要加.all()    # print(book_obj.authors)         # print(book_obj.authors.all())        ID为2的书籍对应多个作者,通过.all()拿到所有作者对象,for循环依次取出对象    # res = book_obj.authors.all()    # for r in res:    #     print(r.name)    书籍和作者是多对多的关系。        正向.字段后得出的结果是app01.Author.None。多对多的关系要加.all()    # 3.查询作者是jason的家庭住址    # author_obj = models.Author.objects.filter(name='jason').first()    # print(author_obj.author_detail.addr)    # 4.查询出版社是东方出版社出版的书籍    # publish_obj = models.Publish.objects.filter(name='东方出版社').first()        # # print(publish_obj.book_set)  # app01.Book.None    反向,当获取多个对象的时候:加_set    # print(publish_obj.book_set.all())    # 5.查询作者是jason的写过的所有的书籍    # author_obj = models.Author.objects.filter(name='jason').first()    # print(author_obj.book_set)  # app01.Book.None    # print(author_obj.book_set.all())    # 6.查询电话号码是130的作者姓名    # author_detail_obj = models.AuthorDetail.objects.filter(phone=130).first()    # print(author_detail_obj.author.name)    """    当你反向查询的结果是多个的时候 就需要加_set    否则直接表明小写即可    """    # 7.查询书籍ID为1 的作者的电话号码    # book_obj = models.Book.objects.filter(pk=1).first()    # author_List = book_obj.authors.all()    # for author_obj in author_List:    #     print(author_obj.author_detail.phone)二、基于双下划綫的跨表查询(连表 *** 作)        left join        inner join        right join        union正向                                                正向     __字段models.Book.objects.filter(name='jason').values('publish__name')    # 1.查询jason作者的手机号    # res = models.Author.objects.filter(name='jason').values('author_detail__phone','author_detail__addr')    # print(res)    # res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone')    # print(res1)    # 查询jason这个作者的年龄和手机号    # 正向    # res = models.Author.objects.filter(name='jason').values('age','author_detail__phone')    # print(res)    # 反向    # res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age')    # print(res1)    # 查询手机号是130的作者年龄    # 正向    # res = models.AuthorDetail.objects.filter(phone=130).values('author__age')    # print(res)    # # 反向    # res1 = models.Author.objects.filter(author_detail__phone=130).values('age')    # print(res1)        # 查询书籍ID是1 的作者的电话号码    只要表中有外键字典就可以无限制的跨表    # res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')    # res1 = models.Book.objects.filter(pk=1).values('外键字段1__外键字段2__外键字段3__普通字段')    # print(res)    """只要表里面有外键字段 你就可以无限制跨多张表"""    # 1.查询出版社为北方出版社的所有图书的名字和价格    # res = models.Publish.objects.filter(name='北方出版社').values('book__Title','book__price')    # print(res)    # 2.查询北方出版社出版的价格大于19的书    # res = models.Book.objects.filter(price__gt=19,publish__name='北方出版社').values('Title','publish__name')    # print(res)    # 聚合查询(aggregate)    # 1.统计所有书的总价格    # from django.db.models import Max,Min,Count,Avg,Sum    #    # # res = models.Book.objects.aggregate(Sum('price'))    # res1 = models.Book.objects.aggregate(Avg('price'))    # res2 = models.Book.objects.aggregate(Count('price'))    # res3 = models.Book.objects.aggregate(Max('price'))    # res4 = models.Book.objects.aggregate(Min('price'))    # res5 = models.Book.objects.aggregate(Max('price'),Min('price'),Count('pk'),Avg('price'),Sum('price'))    # print(res5)    # print(res)    # print(res1)    # print(res2)    # 分组查询    # 统计每一本书的作者个数    from django.db.models import Max,Sum    # res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','Title')    # print(res)    # 统计出每个出版社卖的最便宜的书的价格    # res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')    # print(res)    # 统计不止一个作者的图书    # res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)    # print(res)    """    只要是queryset对象 就可以无限制的调用queryset对象的方法!!!    最最常用的就是对一个已经filter过滤完的数据 再进行更细化的筛选        """    # 查询各个作者出的书的总价格    # res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp')    # print(res)

书籍有多个出版社要.all()

拿到这个结果就说明,写的没错,只是少东西!

反向查

_没有set,则报错

分组查询:models点啥就按啥分组

F查询和Q查询

F查询从数据库获取字段对应的值

增加字段kucun和maichu

看题目:

之前这个数是我们自己指定的,现在是数据库里的数据,怎么写?F查询

F查询就是来解决这一问题的。

需要导入模块:

F查询的本质就是从数据库中获取某个字段的值    # 查询库存数大于卖出数的书籍    """之前查询等号后面的条件都是我们认为输入的        现在变成了需要从数据库中获取数据放在等号后面    """    from django.db.models import F    # res = models.Book.objects.filter(kucun__gt=F('maichu'))    # print(res)    # 将书籍库存数全部增加1000    # models.Book.objects.update(kucun=F('kucun')+1000)    # 把所有书名后面加上'新款'    # from django.db.models.functions import Concat    # from django.db.models import Value    #    # ret3 = models.Book.objects.update(Title=Concat(F('Title'),Value('新款')))    # models.Book.objects.update(Title = F('Title')+'新款')  # 不能这么写

Q查询

看题目:使用Q查询来修改条件

也需要导入模块:

from django. db. models import Q

filter()括号内,逗号是and的关系

Q查询:Q()    from django.db.models import Q    # 查询书籍名称是三国演义或者价格是444.44    与    # res1 = models.Book.objects.filter(Q(Title='三国演义'),Q(price=444))  # 如果用逗号 那么还是and关系    或 |    # res2 = models.Book.objects.filter(Q(Title='三国演义')|Q(price=444))    非 ~    # res3 = models.Book.objects.filter(~Q(Title='三国演义')|Q(price=444))    # print(res2)

Q的高级用法

Q高级用法q = Q()q.connector = 'or'  # 修改查询条件的关系   默认是andq.children.append(('Title__contains','三国演义'))  # 往列表中添加筛选条件# q.children.append(('price__gt',444))  # 往列表中添加筛选条件# res = models.Book.objects.filter(q)  # filter支持你直接传q对象  但是默认还是and关系# print(res)
总结

以上是内存溢出为你收集整理的django(5)全部内容,希望文章能够帮你解决django(5)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1191207.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存