自我总结46
模型层
手动配置测试脚本
# 当你想单独测试django中某一个py文件 你需要手动配置测试脚本
# 1. 从manage.py 复制下面这段到test.py 或者 自己建个新的.py文件
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")
# 2.写入下面两句,配置完成
import django
django.setup()
# 等待测试脚本搭建完毕之后 导入django文件进行测试
from app名字 import models
一对多字段数据的增删改查
默认就是级联删除 级联更新 (django1.X版本默认都是级联关系)
创建数据
1.create方法
from datetime import date
ctime = date.today()
book_obj = models.Books.objects.create(title='红楼梦', price=888.99, publish_date=ctime)
print(book_obj)
2.利用对象的绑定方法
book_obj = models.Books(title='西游记',price=666.66,publish_date='2000-1-21')
book_obj.save()
修改数据
"""
pk会自动帮你查找到当前表的主键字段 所以后期我们都是用pk来指代主键字段
filter查询出来的结果是一个Queryset对象
1.只要是queryset对象就可以 无限制的调用 queryset的方法
res = models.Books.objects.filter(pk=1).filter().filter()
2.只要是queryset对象就可以点query查看当前结果内部对应的sql语句
res.query
SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_date` FROM `app01_books` WHERE `app01_books`.`id` = 1
"""
"""
get和filter区别
1.filter获取到的是一个queryset对象 类似于一个列表
2.get获取到的直接就是数据对象本身
当条件不存在的情况下
filter不报错直接返回一个空 推荐使用filter方法
get直接报错 所以不推荐使用get方法
"""
1.利用queryset方法 filter()
models.Books.objects.filter(pk=1).update(price=444.66)
2.利用对象
book_obj = models.Books.objects.get(pk=1)
book_obj.price = 222.66
book_obj.save()
# 不推荐使用 利用对象的修改 内部其实是重头到位将数据的所有字段都重新写一遍
删除数据
1.利用queryset方法 delete()
models.Books.objects.filter(pk=3).delete()
2.对象方法
book_obj = models.Books.objects.get(pk=3)
book_obj.delete()
查询数据
# 单表操作 13条
# 查数据
1.all() 查询所有
# sql语句查询默认都是惰性查询,只有当你真正要使用数据的时候才会执行orm语句
res = models.Books.objects.all()
2.filter() 筛选 相当于原生sql语句里面的where关键字 返回的结果QuerySet对象
res = models.Books.objects.filter(pk=1,title='三')# 支持多个参数,之间是and关系
3.get() 筛选 获取的数据对象本身 条件不存在直接报错
并且查询条件必须是唯一的
res = models.Books.objects.get(title='西游记')
4.frist() 取queryset中的第一个数据对象
res = models.Books.objects.filter(title='西游记').first()
5.last() 取queryset中的最后一个数据对象
res = models.Books.objects.filter(title='西游记').last()
6.count() 统计数据的个数 数字
num = models.Books.objects.count()
7.values() 获取数据对象中指定的字段的值 可以有多个 queryset 列表套字典
res = models.Books.objects.values('title','price')
<QuerySet [{'title': '三国演义', 'price': Decimal('222.66')}, {'title': '红楼梦', 'price': Decimal('888.99')}, {'title': '西游记', 'price': Decimal('444.66')}, {'title': '西游记', 'price': Decimal('666.22')}]>
8.values_list() 获取数据对象中指定的字段的值 可以有多个 queryset 列表套元组
res = models.Books.objects.values_list('title','price')
<QuerySet [('三国演义', Decimal('222.66')), ('红楼梦', Decimal('888.99')), ('西游记', Decimal('444.66')), ('西游记', Decimal('666.22'))]>
9.order_by() 默认是升序 按照指定的字段排序 (降序 字段前面加负号)
res = models.Books.objects.order_by('price') # 默认是升序
res1 = models.Books.objects.all().order_by('-price') # 降序
10.reverse() 颠倒顺序 (前提是跌倒的对象必须有顺序)
res = models.Books.objects.all()
res1 = models.Books.objects.all().reverse()
res2 = models.Books.objects.all().order_by('price')
res3 = models.Books.objects.all().order_by('price').reverse()
11.exclude() 排除什么什么之外
res = models.Books.objects.all().exclude(title='三国演义')
12.exists() 判断查询结果是否有值 返回一个布尔值
res = models.Books.objects.filter(pk=1).exists() # 该方法其实不需要使用 因为数据本身自带布尔值
13.distinct() 对查询结果进行去重操作 # 去重的前提:数据必须是完全一样的情况下 才能够去重(主键不会一样,很容易忽略)
res = models.Books.objects.values('title','price')
res = models.Books.objects.values('title','price').distinct()
双下划线查询
res = models.表名.objects.filter(字段__xxx方法=条件)
__gt 大于
__lt 小于
__lte 小于等于
__gte 大于等于
__in 或
__range 在···之间
__year 年
__month 月
__startswith 以···开头
__endswith 以···结尾
__contains 包含(默认区分大小写)
__icontains 包含(忽略大小写 加i)
# 模糊查询
关键字 like
符号:
%:匹配任何个数的字符
_:匹配一位任意的字符
# 测试
# 增
add
auto_now
auto_now_add:当数据创建出来的时候 会自动将创建时间记录下来
# 改
set
# 删除
'''
remove既可以传数字 也可以传对象
并且支持多个 不需要迭代
'''
# 清空
'''
clear清空数据相关所有记录,括号内不需要传递参数
'''
多对多字段数据的增删改查
自己直接去操作第三张表
创建数据
add方法 能够朝第三张关系表添加数据
book_obj = models.Book.objects.filter(pk=2).first()
# print(book_obj.publish) # 点外键字段 可能会直接获取到外键关联的数据对象
# print(book_obj.authors) # 已经跨到第三张表了
book_obj.authors.add(1,2) # 支持传数字
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.add(author_obj,author_obj1) #支持传对象
修改数据
set方法
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.set((1,3))
author_obj = models.Author.objects.filter(pk=1).first()
authoe_obj1 = models.Author.objects.fiter(pk=2).first()
book_obj.authors.set((author_obj,author_obj1))
删除数据
remove方法
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.remove(1,2)
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.remove(author_obj,author_obj1)
"""
上面三者都支持传数字和对象 并且都支持传多个
但是需要注意的是
set需要传一个可迭代对象
"""
清空
clear方法 删除某个数据在第三张表中的所有记录
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.clear()
"""
clear清空数据相关所有记录 括号内不需要传递参数
"""
跨表查询
基于对象的跨表查询 子查询
口诀:关系字段在谁那 有谁查谁就是正向
正向查询 按字段
反向查询 小写 + _set
'''
什么时候需要加all
当正向查询点击外键字段数据有多个的情况下,需要.all()
app01.Author.None 一旦看到该结果 只需要加.all()即可
'''
'''
什么时候反向查询的时候表名加set
一对一不需要
一对多,多对多需要
'''
基于双下划线的跨表查询
"""
inner join
left join
right join
union
"""