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)的更多相关文章

  1. Django基础(3)----模型层-单表操作,多表创建

    昨日内容回顾: 1. {% include '' %} 2. extend base.html: <html> ..... ..... ..... {% block content%} { ...

  2. Django基础之模型层(下)

    聚合查询 关键字:aggregate from django.db.models import Max,Min,Sum,Count,Avg 统计所有书的平均价格 models.Book.objects ...

  3. Django基础之模型层(01)

    内容概要 查询关键字 MySQL select    from    where    group by    having    order by    distinct    limit    r ...

  4. Django基础之模型(models)层(上)

    目录 Django基础之模型(models)层 单表查询 必知必会13条 神奇的双下划线查询 多表查询 外键的字段的增删改查 表与表之间的关联查询 基于双下划线的跨表查询(连表查询) 补充知识 Dja ...

  5. Django的日常-模型层(2)

    目录 Django的日常-模型层(2) 几种常用的查询方式 聚合查询 分组查询 F和Q查询 查询优化相关 orm中常见字段 choices参数 orm的事务操作 Django的日常-模型层(2) 几种 ...

  6. Django的日常-模型层(1)

    目录 Django的日常-模型层(1) 模型层 django测试环境 ORM查询 Django的日常-模型层(1) 模型层 模型层其实就是我们应用名下的models.py文件,我们在里面写入想要创建的 ...

  7. Django学习之模型层

    模型层 查看orm内部sql语句的方法的方法 1.如果是queryset对象,那么可以点query直接查看该queryset的内部sql语句 2.在Django项目的配置文件中,配置一下参数即可实现所 ...

  8. Django基础之模板层

    内容概要 模板层(模板语法) 模板语法传值​模板语法过滤器(内置方法)​模板语法标签(流程控制)​自定义过滤器和标签(了解) 模板的导入与继承(面向对象) 内容详细 1 模板层之模板语法传值 http ...

  9. Django基础之路由层

    内容概要 路由匹配 无名有名分组 反向解析 无名有名分组反向解析(难理解) 路由分发 名称空间 伪静态 内容详细 1 路由匹配 urls.py url()方法第一个参数其实是一个正则表达式 第一个参数 ...

随机推荐

  1. TCP的握手和挥手

    三次握手 三次握手具体过程是什么? 客户端发送一个数据包 将SYN置成1,表示希望建立连接 这个包中的序列号是X 服务器收到客户端发来的数据包 通过SYN得知这是一个建立连接的请求 于是发送一个响应包 ...

  2. Hive解析Json数组超全讲解

    在Hive中会有很多数据是用Json格式来存储的,如开发人员对APP上的页面进行埋点时,会将多个字段存放在一个json数组中,因此数据平台调用数据时,要对埋点数据进行解析.接下来就聊聊Hive中是如何 ...

  3. 云空调来自 GitHub 的冷气——GitHub 热点速览 v.21.20

    作者:HelloGitHub-小鱼干 万物皆可上云,air-conditioner 是上周火爆小鱼干朋友圈和公众号信息流的云空调项目.第一眼的时候,你会觉得和这个云空调还挺别致的,第二眼,si~~感到 ...

  4. 03.28,周六,12:00-17:00,ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016正式赛。

    A. Majestic 10 题意:三个数均大于10则输出"triple-double",如果两个数大于10则输出"double-double",如果一个大于1 ...

  5. where优先级

    select name from emply where id >5; 先找表from emply 再找条件 where id >5 最后打印 你想打印的字段 可以把select看成打印 ...

  6. mysql基本命令(增,查,改,删)

    from oldboy egon

  7. docker容器与容器的关联

    可以通过docker run -it -d --link 容器id 镜像id   方式关联 例如,将springboot项目容器与mysql容器相互关联,让springboot容器可以访问到mysql ...

  8. Django(31)模板中常用的过滤器

    模版常用过滤器 在模版中,有时候需要对一些数据进行处理以后才能使用.一般在Python中我们是通过函数的形式来完成的.而在模版中,则是通过过滤器来实现的.过滤器使用的是|来使用. add 将传进来的参 ...

  9. 如何使用GoLand debug

    debug 常用操作 /* 如何使用 goland debug goroutine */ package main import ( "fmt" "runtime&quo ...

  10. xsos:一个在Linux上阅读SOSReport的工具

    xsos:一个在Linux上阅读SOSReport的工具 时间 2019-05-23 14:36:29  51CTO 原文  http://os.51cto.com/art/201905/596889 ...