Django模板层2
一.单表操作
1.1 开启test
from django.test import TestCase
import os
# Create your tests here. if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_6.settings")
import django
django.setup()
from ap01 import models """
1.一对多的表操作 :即book和publish 首先我们先对书籍的数据进行增 删 改 查 x
2.手动加点和数据相关的数据 方便测试
"""
1.2 增
方法一:
# 1.一对多的表操作 >>>书籍:
# (1)增:添加书籍
# 因为书籍中有个publish字段 可以直接加id 也可以加出版社对象
# 方法一:
# res = models.Book.objects.create(title='聊斋志异',price=88.99,publisher_id=2)
# print(res)
方法二:
# 方法二:
# publish_obj = models.Publish.objects.filter(pk=3).first()
# print(publish_obj.name)
# res = models.Book.objects.create(title='西游记',price=666,publisher=publish_obj)
# print(res)
1.3 查
# 1.all()
book_obj = models.Book.objects.all()
print(book_obj)
# 2 filter()
book_obj = models.Book.objects.filter(id=7).first()
print(book_obj) # Book object
# 3.get()
# get()的方法一般不推荐使用 如果内容不存在则会报错
book_obj = models.Book.objects.get(title='红楼梦')
print(book_obj) # Book object # book_obj = models.Book.objects.get(pk=9)
# print(book_obj.title)
1.4 改
# 1.单表的update
# res = models.Book.objects.filter(id=7).update(price=77.66)
# print(res) # 返回值是1 我也不知道是啥
# 2.对象赋值的方式 all() 和filter() 都是Queryset()对象
# book_obj = models.Book.objects.filter(pk=7).first()
# print(book_obj)
# book_obj.title='花花'
# book_obj.save()
原生:
SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
WHERE
`ap01_book`.`id` = 7
ORDER BY
`ap01_book`.`id` ASC
LIMIT 1;
args = ( 7, ) ( 0.000 ) UPDATE `ap01_book`
SET `title` = '花花',
`price` = '77.66',
`publisher_id` = 2
WHERE
`ap01_book`.`id` = 7;
args = ( '花花', '77.66', 2, 7 )
1.5 删
# 删除数据操作 一般不会用 # models.Book.objects.filter(id=6).delete() # 直接删除数据
二.其他查询方法
13条查询方法
all()
filter()
上面俩个查询到的都是 queryset() 对象
get() # 取值一般不推荐使用 查不到会报错
values() # 列表套字典 返回的是一个Queryset()的对象 内部是封装的字典的格式 value()内部支持传多个参数 key 就是我们自己查的字段 value 就是我们要的值
book_obj = models.Book.objects.values('title','price',)
print(book_obj)
# < QuerySet[
# {'title': '三国演义', 'price': Decimal('199.00')}, {'title': '花花', 'price': Decimal('77.66')},
# {'title': '西游记','666.00')}, {'title': '红楼梦', 'price': Decimal('66.44')}] >
values_list() # 列表套元组
# <QuerySet [('三国演义', Decimal('199.00')), ('花花', Decimal('77.66')),
# ('西游记', Decimal('666.00')), ('红楼梦', Decimal('66.44'))]>
# 返回的也是Query set()对象 里面是列表套元组的形式
first() 和last() 返回的是的我们的对象 first() 是取第一个 我们结合filter(pk).first() 其实内部走的是bject[0]
book_obj = models.Book.objects.first()
book3_obj = models.Book.objects.last()
book2_obj = models.Book.objects.filter(pk=8).first()
print(type(book_obj),book_obj)
print(type(book2_obj),book2_obj)
print(type(book3_obj),book3_obj) args = NONE ( 0.000 ) SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
ORDER BY
`ap01_book`.`id` ASC
LIMIT 1;
args = ( ) SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
WHERE
`ap01_book`.`id` = 8
ORDER BY
`ap01_book`.`id` ASC
LIMIT 1;
args = ( 8, )
(0.001)
<class 'ap01.models.Book'> Book object
<class 'ap01.models.Book'> Book object
<class 'ap01.models.Book'> Book object
count()
# count() 统计某个字段的个数
res = models.Book.objects.count() # 这里是不需要进行参传数的
print(res) # return getattr(self.get_queryset(), name)(*args, **kwargs) 颞部原理是反射
exclude()
res =models.Book.objects.filter(pk=7).exists()
print(res) # is_语句 判断是否包含pk=7的对象 True
distinct()
book_obj = models.Book.objects.values('title','publisher').distinct()
print(book_obj) 注意:这里是先获取vlues('字段1',‘字段2‘,’字段3‘) 。distinct()是根据我们要查的字段必须全部一致 如果里面价格’id‘ id 肯定不一样不能实现去除功能
order_by()
print(models.Book.objects.order_by('price')) # 默认是升序
exists() # 判断是否存在
reverse() #
print(models.Book.objects.order_by('price').reverse()) # 先进性排序再将结果进行反序
三。神奇的双下划线
1. 书籍名称中包含
# title__contains = 'p'
# title__icontains = 'p' # 这个忽略打大小写的 也即是P p 是查询只能其中一个匹配一个结果
book_list = models.Book.objects.filter(title__contains='西游')
print(book_list)
原生SQL 语句既是模糊匹配
SELECT `ap01_book`.`id`, `ap01_book`.`title`, `ap01_book`.`price`, `ap01_book`.`publisher_id` FROM `ap01_book` WHERE `ap01_book`.`title` LIKE '%西游%' LIMIT 21; args=('%西游%',)
补充:
关键字:like 是模糊匹配 %西游% 只要有就给你进行筛选出来
% 匹配任意一个 %三 》》》 以上三结尾的所有结果 三% 以三开头的任意字符 %三% 含有三的任意字符
— 只匹配一个字符
2.查询书籍价格大于199 或等于199 书籍对象
print(models.Book.objects.filter(price__gt=199)) # 大于 price 是我们当前的字段
print(models.Book.objects.filter(price__gte=199)) # 大于等于
print(models.Book.objects.filter(price__lt=199)) # 大于等于
print(models.Book.objects.filter(price__lte=199)) # 大于等于
# 原生SQL语句
SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
WHERE
`ap01_book`.`price` <= 199
LIMIT 21;
args = ( DECIMAL ( '199' ), )
3.in 和range
print(models.Book.objects.filter(price__in=(666,199)))
# <QuerySet [<Book: 三国演义>, <Book: 西游记>, <Book: 西游记>]>
# price——in【】 () 容器范围内 SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
WHERE
`ap01_book`.`price` IN ( 666, 199 )
LIMIT 21;
args = ( DECIMAL ( '' ), DECIMAL ( '' ) )
3.price__range() # between 100 and 400
print(models.Book.objects.filter(price__range=(66,199))) # <QuerySet [<Book: 三国演义>, <Book: 西游记>, <Book: 西游记>]>
SELECT
`ap01_book`.`id`,
`ap01_book`.`title`,
`ap01_book`.`price`,
`ap01_book`.`publisher_id`
FROM
`ap01_book`
WHERE
`ap01_book`.`price` BETWEEN 66
AND 199
LIMIT 21;
args = ( DECIMAL ( '' ), DECIMAL ( '' ) )
4.按年份查询
# # 按年查询
# filter(publish_date__year='2019')
user_obj = models.Publish.objects.filter(publish_date__year='2019').all()
user_obj = models.Publish.objects.filter(publish_date__year='2019').all() >>all() 是Queryset() 对象
print(book_obj )
<QuerySet [<Publish: Publish object>, <Publish: Publish object>, <Publish: Publish object>]>
原生SQL
SELECT
`ap01_publish`.`id`,
`ap01_publish`.`name`,
`ap01_publish`.`publish_date`
FROM
`ap01_publish`
WHERE
`ap01_publish`.`publish_date` BETWEEN '2019-01-01'
AND '2019-12-31'
LIMIT 21;
args = ( '2019-01-01', '2019-12-31' ) 按月份查询
user_obj = models.Publish.objects.filter(publish_date__month='8').first()
print(user_obj.publish_date)
四.多表操作
外键字段增删改查
1.一对多 》》》 书籍表和出版社表 外键建立在我们的书籍表中
添加2个作者到我们的书籍id=7 的数据表中
4.1 正向:判断是否查询的结果在我们当前第一条件是否有我们要查的条件 若有就是
# 7.查询书籍id为1 的作者的电话号码
# 思路:正向按字段 反向按表名小写 》》》1.反向规律:如果查询的结果是多 则需要book_set().all()
#
# 1/一看作者的电话号码咱们的这个字段没有啊 那么他和那张表直接关联
# 2/巧了正好我们Book下的author 在我们的表 book_obj.author__
# 反向表名(要查的收机号码在详情表中)小写
book_obj = models.Book.objects.filter(pk=7).first()
# print(book_obj)
author_list = book_obj.authors.all() # 一对多 拿到这本数的所有作者
for auth_obj in author_list:
print(auth_obj.author_detail.phone)
4.2 反向:
# 4.查询出版社 是 东方出版社出版的所有书籍
# 思路:1 出版社 书籍
# 方法一:反向 # publish_obj = models.Publish.objects.filter(name='东方出版社').first()
# print(publish_obj)
# print(publish_obj.book_set.all())
2.多对多:
增:
1.models.Book.objects.create(username='koko',password='123')
2.user_obj = modelsBook(usename='koko',password='123')
user_obj.save()
add() :添加多个:给某个字段添加多个值的时候
给闪过演义的书添加3个作者
book_obj = modles.Book.object.filter(title='三国演义').firest()
通过对象点方法实现 >>> 给那个表加 正向字段 反向 表名小写
book_obj.authors.add(1,2,3) >>> 注意:参数可以是单个数字或单个对象 也可以是多个数字pk 或作者对象
3.set():修改基于已经有得数据进行修改
将三国演义这本书的作者改为4,6
book_obj = modles.Book.objecet.filter(title='三国演义').first()
book_obj.authors.set([1,2]) >>>注意了:这里参数必须是迭代对象 可以单个或多个数字 单个对象或者多个对象
4.remove()
book_obj = modles.Book.objecet.filter(title='三国演义').first()
# 删除书籍是小小的作家
# 方法一:
book_obj = models.Book.objects.filter(title='小小').first()
book_obj.atuhors.remove(1,2) # 参数里面是单个数字和对象 多个数字一般是要删除pk 值不是迭代的容器 和add() 用法一样
#方法二:
author_obj = models.Author.objects.filter(pk=1).first()
book_obj.authors.remove(author_obj)
5.clear()
book_obj = models.Book.objects.filter(pk=14).first()
book_obj.authors.clear() >>> 不需要进行传参数
正向 和反向 多的book_set.all(_)
# 查询书籍id=7的有作者的姓名
book_obj = models.Book.objects.filter(pk=7).first()
print(book_obj.authors.all())
3.一对一
# # 一对一
# 查询作者是koko的家庭住址
# 方法一:正向
# 思路:1.判断是反向还是正向查询 我们条件当前类下 是否有 需要查的类的字段 有>>> 正向(字段) 没有>>>反向(表名小写)
# 2.获取对象
# 3.对象点要查结果的字段.name addr
au_obj = models.Author.objects.filter(name='koko').first() # 只要是Queryset 对象就可以无限的点
print(au_obj.author_detail.addr) # auth_obj = models.Author.objects.filter(name='koko').first()
# print(auth_obj)
# print(auth_obj.author_detail.addr)
五.跨表查询
总结: 总体来说就这两种
1 >>>>基于book_obj 跨表查询
2 >>>>基于authors__name >>> values(authors__name) 返回的是一个列表套字典的对象
一对一双下划线查询
正向:正向按字段 按字段,跨表可以在filter,也可以在values中
反向:按表名小写 >>>按表名小写,跨表可以在filter,也可以在values中 结果是多的话book_set 加上_set.all()
"""基于双下划綫的跨表查询(连表操作)
eft join
inner join
right join
union
"""
# 正向
# 1.查询j查询书籍id的 所有作者的手机号
book_obj = models.Book.objects.filter(pk=7).values('authors__name','authors__author_detail__phone') print(book_obj) """只要表里面有外键字段 你就可以无限制跨多张表""" 最后————phone 普通字段取值
<QuerySet [{'authors__name': 'jason', 'authors__author_detail__phone': 132}, {'authors__name': 'tank', 'authors__author_detail__phone': 133}]>
2。查看koko作者的收机号码
#2. 查询作者是koko 的手机号码(要求一行代码实现 只要有字段就可以无限__)
res = models.Author.objects.filter(name='koko').values('author_detail__phone')
print(res)
# 3 # 查询jason这个作者的年龄和手机号
# 需求:反向查大前提 》》》 正向按自段 反向按表名小写
print(models.Authordetail.objects.filter(author__name='koko').values('author__age','phone'))
# 1.查询书籍id是1 的作者的电话号码 一行代码解决
# 正向
print(models.Book.objects.filter(pk=6).values('authors__author_detail__phone'))
# 2.查询北方出版社出版的价格大于19的书 >>>正向
作业 ```python
"""
1 单表查询:
1 查询南方出版社出版社出版过的价格大于200的书籍
2 查询2017年8月出版的所有以py开头的书籍名称
3 查询价格为50,100或者150的所有书籍名称及其出版社名称
4 查询价格在100到200之间的所有书籍名称及其价格
5 查询所有人民出版社出版的书籍的价格(从高到低排序,去重)
"""
```
六.聚合查询
1.聚合(利用聚合函数)
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。
需要导模块:
from django.db.models import Sum,Max,Min,Avg,Count
# 1求出版社设南方出版社的书籍的的总价
res = models.Book.objects.filter(publisher__name='南方出版社').aggregate(Sum('price'))
print(res)
原生的SQL语句
SELECT
SUM( `ap01_book`.`price` ) AS `price__sum`
FROM
`ap01_book`
INNER JOIN `ap01_publish` ON ( `ap01_book`.`publisher_id` = `ap01_publish`.`id` )
WHERE
`ap01_publish`.`name` = '南方出版社';
args = ( '南方出版社', )
# 2.需求查询出本社是东方出本社的所有书籍的平均价格
res1 = models.Book.objects.filter(publisher__name='东方出版社').aggregate(Avg('price'))
print(res1) # {'price__avg': 110.626667}
# 2.需求查询出所有书籍的平均价格
res = models.Book.objects.filter().all().aggregate(Avg('price'))
print(res) # {'price__avg': 298.077143}
原生sql语句
SELECT
AVG( `ap01_book`.`price` ) AS `price__avg`
FROM
`ap01_book`
INNER JOIN `ap01_publish` ON ( `ap01_book`.`publisher_id` = `ap01_publish`.`id` )
WHERE
`ap01_publish`.`name` = '东方出版社';
args = ( '东方出版社', ) ( 0.000 ) SELECT
AVG( `ap01_book`.`price` ) AS `price__avg`
FROM
`ap01_book`;
args = ( )
七.分组查询
# 3.查询每个出版设的最高价的书名 最低价格的书名
# MAX
from django.db.models import Sum, Max, Min, Avg, Count
res1 = models.Publish.objects.annotate(max=Max('book__price')).values('name','book__title','book__price')
res2 = models.Publish.objects.annotate(min=Min('book__price')).values('name','book__title','book__price')
print(res1)
print(res2)
分组查询
# 统计不止一书籍的作者
res = models.Author.objects.annotate(c=Count('book__title')).filter(c__gt=1)
print(res)
# 统计不止一个作者的书籍
res1 = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
print(res1)
# 查询各个作者出的书的总价格
# 查询各个作者出的书的总价格
res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp') print(res)
<QuerySet [{'name': 'koko', 'sp': Decimal('199.00')}, {'name': 'jason', 'sp': Decimal('276.66')}, {'name': 'tank', 'sp': Decimal('276.66')}]> 原生SQL:
SELECT
`ap01_author`.`name`,
SUM( `ap01_book`.`price` ) AS `sp`
FROM
`ap01_author`
LEFT OUTER JOIN `ap01_book_authors` ON ( `ap01_author`.`id` = `ap01_book_authors`.`author_id` )
LEFT OUTER JOIN `ap01_book` ON ( `ap01_book_authors`.`book_id` = `ap01_book`.`id` )
GROUP BY
`ap01_author`.`id`
ORDER BY
NULL
LIMIT 21;
args = ( )
八.F与Q查询
F查询是在们我们获取字段下面的值进行比较时用
# F(查询条件两端都是数据库数据)
# 给书籍表增加卖出和库存字段
# 1.查询出卖出数大于库存数的商品
# F查询的本质就是从数据库中获取某个字段的对应的值
# 查询库存数 大于 卖出数的书籍
"""之前查询等号后面的条件都是我们认为输入的
现在变成了需要从数据库中获取数据放在等号后面
"""
from django.db.models import F
res = models.Book.objects.filter(stock__gt=F('sale'))
print(res)
#将 库存数 加1000
# 将书籍库存数全部增加1000 新增就是update 更新 models.Book.objects.update(stock=F('stock')+1000)
# 把所有书名后面加上'新款'
# from django.db.models.functions import Concat
# from django.db.models import Value
# ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
# Q(filter里面条件都是与,Q支持与或非)
# 查询书籍名称是三国演义或者价格是69 得结果
from django.db.models import Q
"""
class Q(tree.Node):
"""
"""
Encapsulates filters as objects that can then be combined logically (using
`&` and `|`).
"""
"""
# Connection types
AND = 'AND'
OR = 'OR'
default = AND 默认是and 同时满足得并列关系
"""
# 因为数据的filter 等条件是,and 关系 但是想要或| 是必须得通过Q类方法进行操作得>>>
# 查询书籍名称是三国演义或者价格是444.44
res = models.Book.objects.filter(Q(title='三国演义')|Q(price=69))
print(res)
# 1.查询 卖出数大于100 或者 价格小于100块的
# 2.查询 库存数是100 并且 卖出数不是0 的产品
# 3.查询 产品名包含新款, 并且库存数大于60的
```
九.Q的高级用用法
# Q的高级用法
# 先产生一个校q
q = Q() # 类对像
# 默认还是and 可以通过connection = 'or' 改为或 # q.children.append(('title__contains','三国演义')) # TypeError: append() takes exactly one argument (2 given) q.children.append(('price__gt',200)) # 往列表中添加筛选条件 res = models.Book.objects.filter(q) # filter支持你直接传q对象 但是默认还是and关系 print(res)
Django模板层2的更多相关文章
- Django模板层学习笔记
一. 前言 Django模板层的知识包括标签.过滤器.自定义标签.自定义过滤器以及inclusion_tag,最重要的是模板的继承和导入. 首先模板层最重要的是模板语法,之前我们提过涉及到变量用模板语 ...
- django——模板层
每一个Web框架都需要一种很便利的方法用于动态生成HTML页面. 最常见的做法是使用模板. 模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分. 说白了,模板层就是 ...
- Django模板层
一:模板简介 二:模板语法值变量 三: 模板之过滤器 四: 模板之标签 五:自定义标签和过滤器 一:模板简介 def current_datetime(request): now=datetime ...
- Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)
前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...
- Django模板层之templates
一 模版简介 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now ...
- $Django 模板层(模板导入,继承)、 单表*详(增删改查,基于双下划线的查询)、static之静态文件配置
0在python脚本中使用django环境 import osif __name__ == '__main__': os.environ.setdefault("DJANGO_SETT ...
- $Django 模板层(变量、过滤器 、标签)、自定义(模板过滤器,标签)
1 模版语法之变量:详见源码 -{{ 变量 }}:******重要******{#相当于print了该变量#} {#只写函数名 相当于()执行了#}<p>函数:{{ test }}< ...
- django模板层(templates)
1.基础部分 通过使用模板,就可以在URL中直接调用HTML,它还是松耦合的,灵活性强,而且更容易维护 而且可以将变量通过一定的方式嵌入到HTML中,最终渲染到页面,总的来说基于模板完成了数据与用户之 ...
- django模板层之静态文件引入优化
1.新手使用 我们一般在初学django的情况下,引入django的静态文件一般有如下两种方式: 通过路径引用: <script type="text/javascript" ...
随机推荐
- Java文件中代码
public class MyTextView extends TextView { //在用代码创建的时候调用 public MyTextView(Context context) { this(c ...
- File类 ReadAllBytes() ReadAllLines() ReadAllText()
用 File 类里的 ReadAllLines方法读取文件string[] contents = File.ReadAllLines(@"F:\Users\zhuotu003\Desktop ...
- 用ps 查看线程状态
ps -eLo pid,tid,class,rtprio,ni,pri,psr,pcpu,pmem,stat,wchan:30,comm 线程相关选项: THREAD DISPLAY H Show t ...
- final finalize finally throw throws try catch
什么是finalize()方法 finalize()方法什么时候被调用 参见网址 析构函数(finalization)的目的是什么 final 和 finalize 的区别 final以下参见网址 f ...
- java7和java8新特性
以下来至网址: http://blog.csdn.net/samjustin1/article/details/52268004 Java7 新特性 1.switch中可以使用字符串了 String ...
- c++ 指针类型转换
1.数据类型转换(static_cast) //数据类型转换printf("%d\n", static_cast<int>(10.2)); 2.指针类型转换(reint ...
- HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
目录 文章目录 目录 Amphora 启动 keepalived 启动 haproxy 最后 Amphora 创建一个 loadbalancer 需要占用一到两台 Amphora Instance 作 ...
- CentOS7_装机软件推荐
目录 目录 前言 CentOS7中文支持 Install Yum Fastest Mirror Plugin Install Flash Player Install NTFS-3G Install ...
- Python Module_openpyxl_styles 样式处理
目录 目录 前言 系统软件 Working with styles Styles can be applied to the following aspects Styles模块 Copying st ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_1 mybatis表之间关系分析
4.mybatis中的多表查询 表之间的关系有几种: 一对多 多对一 一对一 多对多 举例: 用户和订单 ...