今日内容概要
- ORM执行SQL语句
- 神奇的双下划线查询
- ORM外键字段的创建
- 外键字段相关操作
- ORM跨表查询
- 基于对象的跨表查询
- 基于双下划线的跨表查询
- 进阶操作
今日内容详细
ORM执行SQL语句
有时候使用ORM操作数据库的效率可能偏低 所以我们是可以自己编写SQL语句的
方式1:使用raw方法
models.User.objects.raw('select * from app01_user;')
方式2:通过导模块的方式
from django.db import connection
cursor = connection.cursor()
cursor.execute('select * from app01_user;')
print(cursor.fetchall())
和操作pymysql的方式差不多
神奇的双下划线查询
'''
只要还是个queryset对象那么就可以无限制的点queryset对象的方法
如:queryset.filter().values().filter().values_list()...
'''
1.查询年龄大于18的用户数据
__gt 大于
res = models.User.objects.filter(age__ge=18)
2.查询年龄小于38的用户数据
__lt 小于
res = models.User.objects.filter(age__lt=18)
3.查询年龄大于等于18的用户数据
__gte 大于等于
res = models.User.objects.filter(age__gte=18)
4.查询年龄小于等于38的用户数据
__lte 小于等于
res = models.User.objects.filter(age__lte=18)
5.查询年龄是18或者28或者38的用户数据
__in 指定数据之一的
res = models.User.objects.filter(age__in=(18, 28, 38))
6.查询年龄是18到38之间的用户数据
__range 之间的
res = models.User.objects.filter(age__range=(18, 38))
7.查询名字中含有j的用户数据
__contains 区分大小写的模糊查询
res = models.User.objects.filter(name__contains='j')
__icontains 不区分大小写的模糊查询
res = models.User.objects.filter(name_icontains='j')
8.查询注册年份是2022的用户数据
__year 年
res = models.User.objects.filter(register_time__year=2022)
'''django框架中有时区问题 不做修改的话查不到 后续再解决'''
ORM外键字段的创建
'''
MySQL数据库的外键关系
一对一
外键字段在查询频率较高的一方
一对多
外键字段在多的一方
多对多
外键字段放在第三张表中
ps:关系的判断可以采用换位思考原则 熟练之后就可以瞬间判断
'''
1.创建基础表(书籍表 出版社表 作者表 作者详情表)
2.确定外键关系
一对多 ORM中与MySQL一致 外键字段建在多的一方
多对多 ORM与MySQL有区别
1.外键字段可以直接建在某张表中(建议查询频率较高的表)
内部会自动帮我们创建第三张关系表
2.自己创建第三张关系表并创建外键字段
一对一 ORM与MySQL一致 外键字段建在查询频率较高的一方
3.ORM创建
针对一对多和一对一同步到表中之后会自动加_id的后缀
publish = models.ForeigenKey(to='Publish', on_delete=models.CASCADE)
author_msg = models.OneToOneField(to='AuthorMsg', on_delete=models.CASCADE)
针对多对多 不会在表中有展示 而是创建第三张表
author = models.ManyToManyField(to='Author')
外表字段相关操作
针对一对多 插入数据可以直接填写表中的实际字段
models.Book.objects.create(name='西游记', price=19.99, publish_id=1)
插入数据可以填写创建表时类的字段名
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.create(name='水浒传', price=29.99, publish=publish_obj)
'''
一对一与一对多一致都可以直接传数字 也可以传对象
'''
针对多对多的关系绑定
1.绑定关系
book_obj = models.Book.objects.filter(pk=1).first()
# 通过对象点外键名点add绑定关系 在第三张关系表中给当前书籍绑定作者
book_obj.author.add(1) # 可以一次传一个
book_obj.author.add(1, 2) # 也可以一次传多个
# 也可以传对象
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book.obj.author.add(author_obj1, author_obj2)
2.修改关系
# 通过对象点外键名点set实现 括号中填写可以被迭代取值的数据类型
book.obj.author.set((1, 2)) # 可以是元组
book.obj.author.set([2, 3]) # 可以是列表
book.obj.author.set({'1':1, '2':2}) # 可以是字典
book.obj.author.set('123') # 甚至可以是字符串
# set是将原本的关系删除在重新按照新的创建 所以原本的关系会不存在
# 当然也可以传对象
author_obj2 = models.Author.objects.filter(pk=2).first()
book.obj.author.set(author_obj1)
book.obj.author.add((author_obj1, author_obj2))
3.删除关系
# 通过对象点外键名点remove实现 括号内填写数字或者对象
book.obj.author.remove(1)
book.obj.author.remove(1, 2)
book.obj.author.remove(author_obj1)
book.obj.author.remove(author_obj1, author_obj2)
4.清空关系
# 通过对象点外键点clear实现
book_obj.author.clear() # 将当前数据对象的关系清空
ORM跨表查询
'''
MySQL中跨表查询思路
子查询
分步操作:将一条SQL语句用括号括起来当做另一条SQL语句的条件
连表操作
先整合多张表之后基于单表查询
inner join 内连接
left join 左连接
right join 右连接
'''
正反向查询的概念
正向查询
从外键字段所在的表数据查询关联的表数据就是正向查询
反向查询
从没有外键字段的表数据查询关联的表数据就是反向查询
ORM跨表查询的口诀
正向查询按外键字段
反向查询按小写表名
基于对象的跨表查询
1.查询主键为1的书籍对应的出版社名称
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish) # 拿到了对应出版社对象
print(book_obj.publish.name) # 拿到了对应出版社名称
2.查询主键为4的书籍对应的作者姓名
book_obj = models.Book.objects.filter(pk=4).first()
print(book_obj.author) # 由于是一对多 所以可能有多个 操作还不够
print(book_obj.author.all()) # 拿到了对应的所有对象
print(book_obj.author.all().values('name')) # 取到了对应的作者名
3.查询jason的电话号码
author_obj = models.Author.objects.filter(name='name').first()
print(author_obj.author_msg.phone)
4.查询北方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='北方出版社').first()
print(publish.book_set) # 小写类名后加上_set不然报错 同样一对多可能有多个
print(publish.book_set.all()) # 拿到了所有对应的对象
print(publish.book_set.all().values('name')) # 拿到了对应的书名
5.查询jason写过的书籍
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set.all().values('name'))
6.查询电话号码是110的作者姓名
author_msg_obj = models.AuthorMsg.objects.filter(phone=110).first()
print(author_msg_obj.author.name)
基于双下划线的跨表查询
1.查询主键为1的书籍对应的出版社名称
print(models.Book.objects.filter(pk=2).values('publish__name'))
2.查询主键为4的书籍对应的作者姓名
print(models.Book.objects.filter(pk=4).values('author__name'))
3.查询jason的电话号码
print(models.Author.objects.filter(name='jason').values('author_msg__phone'))
4.查询北方出版社出版过的书籍
print(models.Publish.objects.filter(name='北方出版社').values('book__name'))
5.查询jason写过的书籍
print(models.Author.objects.filter(name='jason').values('book__name'))
6.查询电话号码是110的作者姓名
print(models.AuthorMsg.objects.filter(phone=110).values('author__name'))
进阶操作
1.查询主键为1的书籍对应的出版社名称
print(models.Publish.objects.filter(book__pk=2).values('name'))
2.查询主键为4的书籍对应的作者姓名
print(models.Author.objects.filter(book__pk=4).values('name'))
3.查询jason的电话号码
print(models.AuthorMsg.objects.filter(author__name='jason').values('phone'))
4.查询北方出版社出版过的书籍
print(models.Book.objects.filter(publish__name='北方出版社').values('name'))
5.查询jason写过的书籍
print(models.Book.objects.filter(author__name='jason').values('name'))
6.查询电话号码是110的作者姓名
print(models.Author.objects.filter(author_msg__phone=110).values('name'))
'''
查询主键为4的书籍对应的作者的电话号码
print(models.AuthorMsg.objects.filter(author__book__pk=4).values('phone'))
print(models.Book.objects.filter(pk=4).values('author__author_msg__phone'))
'''
标签:__,框架,author,models,Django,filter,objects,查询
From: https://www.cnblogs.com/lzjjjj/p/16986050.html