Django基础之模型层(02)
1 重要概念
# 多表查询
"""
正向查询 反向查询 当前查询对象是否含有外键字段
如果有就是正向
没有无则是反向
口诀:
正向查询按外键字段
多对多需要额外再加一个.all()
一对多和一对一不需要加
反向查询按表名小写
一对多与多对多
_set.all()
一对一
不需要加
"""
2 多表查询
#####################基于对象的跨表查询#####################
# 子查询:将一张表的查询结果当做另外一条SQL语句的条件(括号括起来)
# 1.查询书籍主键为4的出版社名称
# 先查询书籍对象
# book_obj = models.Book.objects.filter(pk=4).first()
# 外键字段在书这里 所以是正向查询
# res = book_obj.publish
# print(res)
# print(res.title)
# print(res.addr)
# 2.查询书籍主键为3的作者姓名
# 先查询书籍对象
# book_obj = models.Book.objects.filter(pk=3).first()
# 外键字段在书这里 所以是正向查询
# res = book_obj.authors
# print(res) # app01.Author.None
# res = book_obj.authors.all()
# print(res) # <QuerySet [<Author: 作者对象:oscar>, <Author: 作者对象:egon>]>
# 3.查询作者jason的地址
# 先查询jason数据对象
# author_obj = models.Author.objects.filter(name='jason').first()
# 外键字段在作者这里 所以是正向查询
# res = author_obj.author_detail
# print(res)
# print(res.addr)
# print(res.phone)
# 4.查询东方出版社出版的书籍
# 先查询出版社对象
# publish_obj = models.Publish.objects.filter(title='东方出版社').first()
# 外键字段在书那里自己没有 所以是反向
# res = publish_obj.book_set
# print(res) # app01.Book.None
# res = publish_obj.book_set.all()
# print(res)
# 5.查询jason写过的书籍
# 先查询jason数据对象
# author_obj = models.Author.objects.filter(name='jason').first()
# 外键字段在书那里自己没有 所以是反向
# res = author_obj.book_set
# print(res) # app01.Book.None
# res = author_obj.book_set
# print(res) # app01.Book.None
# res = author_obj.book_set.all()
# print(res) # app01.Book.None
# 6.查询电话是120的作者
# 先查询120数据对象
# author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
# 外键字段在作者那里本身没有 所以是反向
# res = author_detail_obj.author
# print(res)
# print(res.name)
# print(res.age) ########################基于双下滑线的跨表查询
# 1.查询书籍主键为4的出版社名称
# res = models.Book.objects.filter(pk=4).values('publish__title','publish__addr','title')
# print(res)
# 2.查询书籍主键为3的作者姓名
# res = models.Book.objects.filter(pk=3).values('authors__name')
# print(res)
# 3.查询作者jason的地址
# res = models.Author.objects.filter(name='jason').values('author_detail__addr','name','age')
# print(res)
# 4.查询北方出版社出版的书籍名称
# res = models.Publish.objects.filter(title='北方出版社').values('book__title')
# print(res)
# 5.查询jason写过的书籍
# res = models.Author.objects.filter(name='jason').values('book__title','name','age')
# print(res)
# 6.查询电话是120的作者
# res = models.AuthorDetail.objects.filter(phone=120).values('author__name','author__age','addr')
# print(res) ############进阶操作#############
# 1.查询书籍主键为4的出版社名称
# res = models.Book.objects.filter(pk=4).values('publish__title','publish__addr','title')
# print(res)
# 反向查询高阶部分
# res = models.Publish.objects.filter(book__pk=4)
# print(res)
# 2.查询书籍主键为3的作者姓名
# res = models.Book.objects.filter(pk=3).values('authors__name')
# print(res)
# 反向查询高阶部分
# res = models.Author.objects.filter(book__pk=3)
# print(res)
# 3.查询作者jason的地址
# res = models.Author.objects.filter(name='jason').values('author_detail__addr','name','age')
# print(res)
# 反向查询高阶部分
# res = models.AuthorDetail.objects.filter(author__name='jason')
# print(res)
# 查询书籍主键为3的作者的电话号码
# res = models.Book.objects.filter(pk=3).values('authors__author_detail__phone')
# print(res)
# res = models.AuthorDetail.objects.filter(author__book__pk=3).values('phone')
# print(res)
# res = models.Author.objects.filter(book__pk=3).values('author_detail__phone')
# print(res)

3 F查询
# F查询
from django.db.models import F
# 1.查询库存数大于卖出数的书籍
# res = models.Book.objects.filter(kucun__gt=F('maichu'))
# print(res)
# 2.将所有的书籍价格上涨100块
# res = models.Book.objects.update(price=F('price') + 100)
# print(res)
# 3.将所有的书籍名称加上"爆款"后缀
'''针对字符串不能直接拼接 需要额外导入模块操作'''
# models.Book.objects.update(title=F('title') + '爆款')
# from django.db.models.functions import Concat
# from django.db.models import Value
# ret3 = models.Book.objects.update(title=Concat(F('title'), Value('爆款')))
4 Q查询
# 1.查询书名是三国演义爆款或者库存是100的书籍
'''filter()括号内可以写多个参数 逗号隔开 默认只支持and连接'''
from django.db.models import Q
# res = models.Book.objects.filter(title='三国演义爆款',kucun=100)
# print(res)
# res1 = models.Book.objects.filter(Q(title='三国演义爆款'),Q(kucun=100)) # and
# res1 = models.Book.objects.filter(Q(title='三国演义爆款')|Q(kucun=100)) # or
# res1 = models.Book.objects.filter(~Q(title='三国演义爆款')|Q(kucun=100)) # not
# print(res1.query)
'''Q进阶用法'''
# condition = input('请输入你需要按照什么字段查询数据>>>:')
# data = input('请输入你需要查询的数据名称>>>:')
# q = Q() # 生成一个Q对象
# q.children.append((condition,data))
# res = models.Book.objects.filter(q)
# print(res)
q = Q()
q.connector = 'or' # 可以修改连接条件
q.children.append(('title__contains','三'))
q.children.append(('price__gt',200)) # 可以添加多个条件 并且也是and关系
res = models.Book.objects.filter(q)
print(res)
print(res.query)

5 事务
"""
1.事务四大特性 ACID
原子性
一致性
独立性
持久性
2.数据库设计三大范式
课下百度搜索自己概括
MySQL
start transcation
commit
rollback
"""
from django.db import transaction
try:
with transaction.atomic():
# 创建一条订单数据
models.Order.objects.create(num="110110111", product_id=1, count=1)
# 能执行成功
models.Product.objects.filter(id=1).update(kucun=F("kucun") - 1, maichu=F("maichu") + 1)
except Exception as e:
print(e)
6 执行原生SQL语句
res = models.Book.objects.raw('select * from app01_book')
for i in res:
print(i)
7 模型层字段及参数
models.AutoField(primary_key=True)
models.CharField(max_length=32) # varchar(32)
models.IntergeField() # int()
models.DateField() # date
models.DateTimeField() # datetime
auto_now
auto_now_add
models.DecimalField() # float()
models.BooleanField()
给这个字段传布尔值会自动转换成数字0或1
一般用在状态二选一
TextField()
存储大段文本(bbs项目会使用)
EmailField()
存储邮箱格式数据
FileField()
存储数据路径(bbs项目会使用)
"""自定义字段"""
from django.db.models import Field
class MyCharField(Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
super().__init__(max_length=max_length,*args,**kwargs)
def db_type(self, connection):
return 'char(%s)'%self.max_length

8 常见参数
max_length
varbose_name
default
null
auto_now
auto_now_add
to
unique
db_index
choices
# choices参数
创建用户表
性别
两到三种状态
学历
也是有限个
在职状态
也是有限个
婚姻
也是有限个
...
"""针对某个字段可以列举完全的情况 一般都是使用choices参数"""
class Server(models.Model):
host = models.CharField(max_length=32)
status_choices = (
(1,'在线'),
(2,'待上线'),
(3,'宕机'),
(4,'待上架')
)
status = models.IntegerField(choices=status_choices)
desc_choices = (
('哈哈','哈哈哈哈哈哈'),
('呵呵','呵呵呵呵呵呵'),
('嘿嘿','嘿嘿嘿嘿嘿嘿'),
('嘻嘻','嘻嘻嘻嘻嘻嘻'),
)
desc = models.CharField(max_length=32,choices=desc_choices)
# 获取对应关系
.get_字段名_display()
9 ORM查询优化
# 惰性查询
用不到的数据即使写了orm语句也不会执行
1.only与defer
2.select_related与prefech_related
# 1.only与defer
# res = models.Book.objects.values('title') # 列表套字典
# res1 = models.Book.objects.only('title') # 列表套对象
# print(res1)
# for i in res1:
# # print(i.title)
# print(i.price)
"""
only括号内写什么字段
生成的对象就含有对应的属性 在查找该属性的时候不再走数据库查询
但是一旦查找括号内没有的字段属性 则每次都会走数据库查询
"""
# res1 = models.Book.objects.defer('title')
# # print(res1) # 列表套对象
# for i in res1:
# # print(i.title)
# print(i.title)
"""
defer与only刚好相反
生成的对象就不含有对应的属性 在查找该属性的时候需要每次走数据库查询
但是一旦查找括号内没有的字段属性 则不需要走数据库查询
"""
# res = models.Book.objects.filter(pk=3).first()
# print(res.publish.title)
# res = models.Book.objects.select_related('publish')
# for i in res:
# print(i.publish.title)
"""
select_related相当于连表操作
先将models后面的表和括号内外键字段关联的表连接起来
之后一次性把所有的数据封装到数据对象中
"""
res = models.Book.objects.prefetch_related('publish')
for i in res:
print(i.publish.title)
"""
prefetch_related相当于子查询
先查询models后面的表的所有的数据
然后将括号内关联的表的数据全部查询出来
之后整合到一起
"""

Django基础之模型层(02)的更多相关文章
- Django基础(3)----模型层-单表操作,多表创建
昨日内容回顾: 1. {% include '' %} 2. extend base.html: <html> ..... ..... ..... {% block content%} { ...
- Django基础之模型层(下)
聚合查询 关键字:aggregate from django.db.models import Max,Min,Sum,Count,Avg 统计所有书的平均价格 models.Book.objects ...
- Django基础之模型层(01)
内容概要 查询关键字 MySQL select from where group by having order by distinct limit r ...
- Django基础之模型(models)层(上)
目录 Django基础之模型(models)层 单表查询 必知必会13条 神奇的双下划线查询 多表查询 外键的字段的增删改查 表与表之间的关联查询 基于双下划线的跨表查询(连表查询) 补充知识 Dja ...
- Django的日常-模型层(2)
目录 Django的日常-模型层(2) 几种常用的查询方式 聚合查询 分组查询 F和Q查询 查询优化相关 orm中常见字段 choices参数 orm的事务操作 Django的日常-模型层(2) 几种 ...
- Django的日常-模型层(1)
目录 Django的日常-模型层(1) 模型层 django测试环境 ORM查询 Django的日常-模型层(1) 模型层 模型层其实就是我们应用名下的models.py文件,我们在里面写入想要创建的 ...
- Django学习之模型层
模型层 查看orm内部sql语句的方法的方法 1.如果是queryset对象,那么可以点query直接查看该queryset的内部sql语句 2.在Django项目的配置文件中,配置一下参数即可实现所 ...
- Django基础之模板层
内容概要 模板层(模板语法) 模板语法传值模板语法过滤器(内置方法)模板语法标签(流程控制)自定义过滤器和标签(了解) 模板的导入与继承(面向对象) 内容详细 1 模板层之模板语法传值 http ...
- Django基础之路由层
内容概要 路由匹配 无名有名分组 反向解析 无名有名分组反向解析(难理解) 路由分发 名称空间 伪静态 内容详细 1 路由匹配 urls.py url()方法第一个参数其实是一个正则表达式 第一个参数 ...
随机推荐
- 使用Layui、Axios、Springboot(Java) 实现EasyExcel的导入导出(浏览器下载)
实现EasyExcel的导入导出(浏览器下载) 实现三个按钮的功能,但是却花费了一天的时间包括总结. 使用到的技术:springboot layui axios EasyExcel mybatis-p ...
- 【技术博客】基于vue的前端快速开发(工具篇)
一.Vue教程 vue.js是一套构建用户界面的渐进式框架.vue采用自底向上增量开发的设计.vue的核心库只关心视图层,非常容易学习,非常容易与其它库和已有项目整合.vue完全有能力驱动采用单文件组 ...
- CSS变量和浏览器前缀
一.CSS变量 CSS变量是CSS的新特性,大多数浏览器都实现了这个功能,使用CSS变量有利代码复用,而且当我们修改变量值时,所有引用该变量的属性都会发生改变. 定义变量后可以有两种使用方法,第一种时 ...
- GCC链接时库顺序问题
GCC或G++在编译链接时,如果命令行中含有库,则要特别注意了.根据<C专家编程>5.3节中的提示,GCC在链接时对命令行时的处理顺序是从左到右.证据是GCC的MAN: -l librar ...
- 单用户模式修改root密码
单用户模式修改root密码 1.进入引导菜单界面2.按e进入grub,在linux或linux16那行结尾加上 rw init=/bin/bash,按Ctrl+x或F103.进入bash-4.3# , ...
- 【山外笔记-SVN命令】svn命令详解
本文打印版文件下载地址 [山外笔记-SVN命令]svn命令详解-打印版.pdf 一.命令简介 svn命令用于Subversion命令行客户端,执行svn相关的操作. 二.命令语法 1.svn语法: ( ...
- Tomcat修改jdk版本
tomcat修改jdk版本 修改tomcat bin目录下的catalina.sh和setclasspath.sh文件,添加以下内容 export JAVA_HOME=/home/nodemanage ...
- bond4以及vlan子接口配置
场景: 前提,交换机的配置由网络工程师配合! 1.跨交换机做bond,模式为LACP,linux双网卡做bond4,模式为4: 2.系统为centos7.0-123: 3.服务器仅有两张万兆网卡,为e ...
- 云计算OpenStack核心组件---cinder存储服务(10)
一.cinder介绍 1.Block Storage 操作系统获得存储空间的方式一般有两种: (1)通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区.格式化.创建文件系统: ...
- Linux服务之nginx服务篇一(概念)
nginx官网:http://nginx.org/ 一. nginx和apache的区别 Nginx: 1.轻量级,采用 C 进行编写,同样的 web 服务,会占用更少的内存及资源. 2.抗并发,ng ...
