Djangoday06

Djangoday06

一、ORM执行SQL语句

有时候ORM的操作效率比较低 ORM也提供了执行SQL语句
通过ORM提供的方式编写SQL语句有三种方式 今天先两种

1.raw

models.User.objects.raw('select * from app01_user')

2.connection

from django.db import connection
cursor = connection.cursor()
cursor.excute('select name form app01_user;')
print(cursor.fetchall())

二、神奇的双下划线查询

只要还是queryset对象就可以无限制的点queryset对象的方法
比如:queryset.filter().values().values_list().filter()....

1.查询年龄大于18岁的用户数据/年龄小于38岁的用户数据

res = models.Users.objects.filter(age__gt=18)  # 大于18岁
res = models.Users.objects.filter(age__lt=38)  # 小于18岁

2.查询年龄大于等于18岁的用户数据/年龄小于等于38岁的用户数据

res = models.Users.objects.filter(age__gte=18)  # 大于等于18岁
res = models.Users.objects.filter(age__lte=38)  # 小于等于18岁

3.查询年龄是18岁或28岁或38岁的用户数据

res = models.User.objects.filter(age__in=(18, 28, 38))

4.查询年龄在18岁到38岁之间所有用户数据

res = models.User.objects.filter(age__range=(18, 38))

5.查询名名字中含有字母j的用户数据

res = models.User.objects.filter(name__contains='j')  # 只查j不查J字母
res = models.User.objects.filter(name__incontains='j')  # J,j都会查出来

6.查询注册年份是2022年的用户数据

res = models.User.objects.filter(register_time__year=2022)

三、ORM外键字段创建

1.ORM外键字段创建理论铺垫

MySQL外键关系
一对多:外键字段在多的一方
多对多:外键字段统一建在第三张关系表
一对一:建议放在查询频率较高的表
ORM确定外键关系
一对多:外键字段在多的一方 跟MySQL一致
多对多:外键字段建在查询频率较高的表(内部自动创建第三张表) 
一对一:建议放在查询频率较高的表 跟MySQL一致
ORM创建外键字段代码语句
针对一对多和一对一同步到表中之后会自动加_id的后缀
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
author_detail = models = models.OneToOneFiled(to='AuthorDetail', on_delete=models.CASCADE)
针对多对多不会在表中展示而是创建第三张表
authers = models.ManyToManyField(to='Author')

2.ORM外键字段创建相关操作

# 针对一对多 插入数据可以直接填写表中的实际字段
models.Book.objects.create(title='编程基础教学', price=888.88, publish_id=1)
models.Book.objects.create(title='编程进阶教学', price=999.99, publish_id=1)
# 针对一对多 插入数据也可以填写表中的类中字段
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.create(title='高级编程指导书', price=1000, publish=publish_obj)

'''一对一与一对多 一致'''
既可以传数字也可以传对象
# 针对多对多关系绑定
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.add(1)  # 在第三张关系表中给当前书籍绑定作者
book_obj.authors.add(2, 3)
book_obj = models.Book.objects.filter(pk=4).first()
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book_obj.authors.add(author_obj1)
book_obj.authors.add(author_obj1, author_obj2)
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.set((1, 3))  # 修改关系
book_obj.authors.set([2, ])  # 修改关系
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book_obj.authors.set((author_obj1,))
book_obj.authors.set((author_obj1, author_obj2))
book_obj.authors.remove(2)
book_obj.authors.remove(1, 3)
book_obj.authors.remove(author_obj1,)
book_obj.authors.remove(author_obj1,author_obj2)
book_obj.authors.clear()
# 总结
add()\remove()	     多个位置参数(数字 对象)
set()			    可迭代对象(元组 列表) 数字 对象 
clear()			    情况当前数据对象的关系

四、多表查询(基于对象和双下划线)

1.ORM跨表查询理论

MySQL跨表查询
子查询:分布操作(将一条SQL语句用括号括起来当作另外一条SQL语句的条件)
连表操作:先整合多张表之后基于单表查询即可('inner'/left/right/union join)
正反向查询(重要)
正向:由外键字段所在的表数据查询关联的表查询
反向:无外键字段的表数据查询关联的表数据查询
# 技巧:核心就看外键字段在不在当前数据所在的表中
ORM跨表查询口诀(重要)
正向查询按外键字段
反向查询按表名小写

2.基于对象的跨表查询

# 1.查询主键为1的书籍对应的出版社名称
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=1).first()
# 再判断正反向的概念  由书查出版社 外键字段在书所在的表中 所以是正向查询
print(book_obj.publish.name)
# 2.查询主键为4的书籍对应的作者姓名
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=4).first()
# 再判断正反向的概念  由书查作者 外键字段在书所在的表中 所以是正向查询
print(book_obj.authors)  # app01.Author.None
print(book_obj.authors.all())
print(book_obj.authors.all().values('name'))
# 3.查询almira的电话号码
author_obj = models.Author.objects.filter(name='almira').first()
print(author_obj.author_detail.phone)
# 4.查询北方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='新疆维吾尔出版社').first()
print(publish_obj.book_set)  # app01.Book.None
print(publish_obj.book_set.all())
# 5.查询almira写过的书籍
author_obj = models.Author.objects.filter(name='almira').first()
print(author_obj.book_set)  # app01.Book.None
print(author_obj.book_set.all())
# 6.查询电话号码是18988998899的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=18988998899).first()
print(author_detail_obj.author)
print(author_detail_obj.author.name)

3.基于双下划线的跨表查询

 # 1.查询主键为1的书籍对应的出版社名称
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res)
# 2.查询主键为4的书籍对应的作者姓名
res = models.Book.objects.filter(pk=4).values('title', 'authors__name')
print(res)
 # 3.查询almira的电话号码
res = models.Author.objects.filter(name='almira').values('author_detail__phone')
print(res)
# 4.查询北方出版社出版过的书籍名称和价格
res = models.Publish.objects.filter(name='新疆维吾尔出版社').values('book__title','book__price','name')
print(res)
# 5.查询almira写过的书籍名称
res = models.Author.objects.filter(name='almira').values('book__title', 'name')
print(res)
# 6.查询电话号码是110的作者姓名
res = models.AuthorDetail.objects.filter(phone=110).values('phone', 'author__name')
print(res)

4.进阶操作

# 1.查询主键为1的书籍对应的出版社名称
res = models.Publish.objects.filter(book__pk=1).values('name')
print(res) 
# 2.查询主键为4的书籍对应的作者姓名
res = models.Author.objects.filter(book__pk=4).values('name','book__title')
print(res)
# 3.查询almira的电话号码
res = models.AuthorDetail.objects.filter(author__name='almira').values('phone')
print(res)
# 4.查询北方出版社出版过的书籍名称和价格
res = models.Book.objects.filter(publish__name='新疆维吾尔出版社').values('title','price')
print(res)
# 5.查询almira写过的书籍名称
res = models.Book.objects.filter(authors__name='almira').values('title')
print(res)
# 6.查询电话号码是18988998899的作者姓名
res = models.Author.objects.filter(author_detail__phone=18988998899).values('name')
print(res)

5.补充说明

# 查询主键为4的书籍对应的作者的电话号码
res = models.Book.objects.filter(pk=4).values('authors__author_detail__phone')
print(res)
res = models.AuthorDetail.objects.filter(author__book__pk=4).values('phone')
print(res)
res = models.Author.objects.filter(book__pk=4).values('author_detail__phone')
print(res)
posted @ 2022-12-15 23:48  阿丽米热  阅读(17)  评论(0编辑  收藏  举报
Title