模型层
如何查询orm语句内部真正的sql语句的两种方式
- 如果是queryset对象,可以直接点query查看
- 配置文件中,直接配置
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level': 'DEBUG',
},
}
}
django测试环境的搭建
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "one_search.settings")
import django
django.setup()
# 写完以上代码就可以在django测试任何的py文件
单表操作
增
方式1:
models.表名.objects.create(键=值,...)
方式2:
obj = models.表名(键=值,...)
obj.save()
改
方式1:
models.表名.objects.filter(pk=1).update(键=值,...)
方式2:
obj = models.表名.objects.filter(pk=1).first()
obj.键 = 值
...
obj.save()
删
models.表名.objects.filter(pk=1).delete()
查
必知必会十三个操作:
- all() 查询所有
res = models.表名.objects.all()
- filter() 条件查询
res = models.表名.objects.filter(x=123)
- get() 查询出对象本身,查不到还会报错,也是条件查询,必须携带参数
res = models.表名.objects.get(pk=1)
- first() 取第一个
res = models.表名.object.all().first()
- last() 取最后一个
res = models.表名.object.all().last()
- exclude() 取除此之外的,返回满足条件之外的
res = models.表名.objects.exclude(pk=1)
- values() 返回列表套字典,参数是字段名,不写参数返回所有的键值
res = models.表名.objects.values('字段名')
- values_list() 列表套元组,参数是字段名,不写参数返回所有的值,没有键
res = models.表名.objects.values_List('字段名')
- count() 统计数据的个数,没有参数
res = models.表名.objects.count()
- distinct() 去重,查询出来所有的字段全都一样才可以去重
res = models.表名.objects.values('字段名').distinct()
- order_by() 排序(默认是升序,加负号就是降序)
res = models.表名.objects.order_by('字段名')
res = models.表名.objects.order_by('-字段名')
res = models.表名.objects.order_by('字段名').reverse()
- reverse() 反转(但是必须是排序好的才可以反转)
res = models.表名.objects.order_by('字段名').reverse()
- exists() 判断查询的东西是否存在
# 简称p用没得
res = models.表名.objects.filter(pk=123).exists()
神奇的双下滑线查询
# 查询价格大于200的书籍
res = models.Book.objects.filter(price__gt=200)
# 查询价格小于200的书籍
res = models.Book.objects.filter(price__lt=200)
# 查询价格大于等于200的书籍
res = models.Book.objects.filter(price__gte=200)
# 查询价格小于等于200的书籍
res = models.Book.objects.filter(price__lte=200)
# 查询价格是200或者是300或者是400其中的一个
res = models.Book.objects.filter(price__in=[200, 300, 400])
// 后面只要是可迭代对象就可以了,也可以写成元组
# 查询价格在200到700之间的书籍
res = models.Book.objects.filter(price__range=(200,700))
// 顾头不顾尾
模糊匹配
就是sql语句中的 like
# 查询书籍名称中包含p的书籍
res = models.Book.objects.filter(name__contains='p') // 区分大小写
res = models.Book.objects.filter(name__icontains='p') // 加个i就不区分大小写了
# 查询书籍名称中以'西'开头的书籍
res = models.Book.objects.filter(name__startswitch='西')
# 查询数据名称是以'记'结尾的书籍
res = models.Book.objects.filter(name__endswitch='记')
# 查询书籍发布日期为2019年的书籍
res = models.Book.objects.filter(data__year='2019')
# 查询书籍发布日期为10月的书籍
res = models.Book.objects.filter(data__month='10')
多表操作
一对多字段增删改查
增
models.表名.objects.create(键=值,外键_id=1) # 外键_id=1 也可以写成 外键=obj
查
res = models.表名.objects.filter(pk=1).first
print(res.外键字段) -> 这个拿到的是对应的对象
print(res.外键字段_id) -> 这个拿到的是外键字段对应表的id
改
models.Book.objects.filter(pk=1).update(publish_id=3)
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)
删
默认是级联删除,所以不要轻易删除数据
models.表名.objects.filter(pk=1).delete()
分析
其实一对多的增删改查也就可以把对应的id换成所查询出来的对象,对象默认取得也是id,
也只是键的不同,键_id
对应数字
,键
对应Queryset对象
多对多字段的增删改查
增
# 为主键为3的书籍添加两个作者1,2
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.add(1,2)
如果两方是多对多关系,有外键的一方可以通过`对象.外键`的方式去设置
add()括号里面也可以传递对象
修改关系
# 修改主键为3的书籍作者为2,3
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.set([2,3])
set()括号里面必须是可迭代对象,里面也是既可以串数字也可以传对象
删除
# 只删除主键为3的书籍的作者2
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.remove(2) -> 指定删除
# 删除主键为3的所有对应关系
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.clear()
多表查询
ORM跨表查询
- 子查询
- 跨表查询
正反向的概念
- 外键字段在哪里,那个表查被外键关联的表,就是正向
- 谁手里有外键字段 谁就是正向查
- 没有外键字段就是反向
- 正向查询按字段,反向查询按表名小写
题目是最好的理解方式
查询书籍是西游记的出版社名称
1. 方式1(基于对象的跨表查询):
book_obj = models.Book.objects.filter(name='西游记').first()
res = book_obj.publish.name # publish是外键
2. 方式2(连表查询:正向)
res = models.Book.objects.filter(name='西游记').values('publish__name')
3. 方式3(连表查询:反向)
res = models.Pubulish.filter(book_name='西游记').values(name)
查询出版社是上海出版社出版的书籍名称
1. 方式1(基于对象的跨表查询):
obj = models.Publish.object.filter(name='上海出版社').first()
print(obj.book_set) -> app01.Publish.None 这个并不是没查出来,而是因为他是多个值
res = obj.book_set.all()
2. 方式2(连表查询:正向)
res = models.Book.objects.filter(publish__name='上海出版社').values('name')
3. 方式3(连表查询:反向)
res = models.Publish.object.filter(name='上海出版社').values('book__name')
查询书籍id是4的作者的手机号
1. 方式1(基于对象的跨表查询):
book_obj = models.Book.objects.filter(pk=4).first()
res = book_obj.authors.all()
for i in res:
author_obj = models.Author.objects.filter(pk=i.id).first()
print(author_obj.AuthorInfo.tel)
2. 方式2(连表查询:正向)
res = models.Book.objects.filter(pk=4).values('authors__AuthorInfo__tel')
3. 方式3(连表查询:反向)
res = models.AuthorInfo.objects.filter(author__book__id=4).values('tel')