一.双下划线查询
models.类名.objects.filter(查询条件)
'这个查询添加是根据数据库里表内的条件进行的'
__gt # 大于 age__get=20
__lt # 小于
__gte # 大于等于 age__get>=20
__lte # 等于小于
__in # 成员运算 age__in=[20,18,19]
__range # 范围查找 []
__contains # 字母查找'应该算字符串查找' name__contains='j'
__icontains # 不分大小写
__month # 查找月份 time__month=5
__year # 年份查找
__startswith # 已什么开始
__endswith # 已什么接受
__regex # 正则
filter 筛选
all 全部
二.外键关系创建
from django.db import models
# Create your models here.
class Book(models.Model):
book_name = models.CharField(max_length=64)
book_money = models.IntegerField()
op_time = models.DateField(auto_now=True)
book_dir = models.ForeignKey(to='Press')
is_book_dir = models.ManyToManyField(to='Author')
def __str__(self):
return '%s书本对象' % self.book_name
class Press(models.Model):
press_name = models.CharField(max_length=64)
models.CharField()
press_addr = models.CharField(max_length=64)
def __str__(self):
return '%s出版对象' % self.press_name
class Author(models.Model):
author_name = models.CharField(max_length=64)
author_age = models.IntegerField()
author_dir = models.OneToOneField(to='Addr')
def __str__(self):
return '%s作者对象' % self.author_name
class Addr(models.Model):
mobile = models.IntegerField()
is_addr = models.CharField(max_length=64)
def __str__(self):
return '%s详情对象' % self.is_addr
# 一对一关系
OneToOneField
'创建在查找多的一方'
# 多对多关系
ManyToManyField
'不用创建第三张表,创建在方便查的一方'
# 一对多关系
ForeignKey
'外键创建多的一方'
'''django orm外键字段针对多对多关系 可以不用自己创建第三张表'''
eg:
to用于指定跟哪张表有关系 自动关联主键
to_field\to_fields 也可以自己指定关联字段
三.外键字段操作
1.一对多、一对一外键字段操作
# 增 关键字create
from app01 import models
方式1:
book_obj = models.Press.objects.filter(pk=1).first()
models.Book.objects.create(book_name='九阳真经', book_money=666, book_dir=book_obj)
方式2:
models.Book.objects.create(book_name='九阴真经',book_money=999,book_dir_id=1)
# 改 关键字update
方式1:
models.Book.objects.filter(pk=1).update(book_dir=2)
方式2:
book_obj = models.Press.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(book_dir=book_obj)
2.多对多 外键字段操作
# 增 关键字add
方式1:
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.is_book_dir.add(1,2)
方式2:
book_obj = models.Book.objects.filter(pk=1).first()
res = models.Author.objects.filter(pk=1).first()
book_obj.is_book_dir.add(res)
# 改 关键字set
方式1:
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.is_book_dir.set([2, ])
方式2:
book_obj = models.Book.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=1).first()
book_obj.is_book_dir.set([author_obj1, ])
# 移除 关键字remove
方式1:
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.is_book_dir.remove(1)
方式2:
book_obj = models.Book.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=1).first()
book_obj.is_book_dir.remove(author_obj1)
# 清空 关键字 clear
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.is_book_dir.clear()
四.多表查询
"""
MySQL多表查询思路
子查询
将SQL语句用括号括起来当做条件使用
连表操作
inner join\left join\right join\union
django orm本质还是使用的上述两种方法
子查询>>>:基于对象的跨表查询
连表操作>>>:基于双下划线的跨表查询
"""
# 正反向的概念
核心在于当前数据对象是否含有外键字段 有则是正向 没有则是反向
正向
eg:
由书籍查询出版社 外键字段在书籍表中 那么书查出版社就是'正向'
由书籍查询作者 外键字段在书籍表中 那么书查作者就是'正向'
由作者查询作者详情 外键字段在作者表中 那么也是'正向'
反向
eg:
由出版社查询书籍 外键字段不在出版社表 那么出版社查书就是'反向'
...
"""
查询口诀
正向查询按外键字段名
反向查询按表名小写
"""
# 编写orm跟编写SQL语句一样 不要总想着一步到位!!!
五.多表查询练习题
"""基于对象的跨表查询本质就是子查询即分步操作即可"""
1.查询数据分析书籍对应的出版社
先获取书籍对象
book_obj = models.Book.objects.filter(title='数据分析').first()
再使用跨表查询
res = book_obj.publish
print(res) # 出版社对象:北方出版社
2.查询python全栈开发对应的作者
先获取书籍对象
book_obj = models.Book.objects.filter(title='python全栈开发').first()
再使用跨表查询
res = book_obj.authors # app01.Author.None
res = book_obj.authors.all()
print(res) # <QuerySet [<Author: 作者对象:jason>, <Author: 作者对象:jerry>]>
3.查询作者jason的详情信息
先获取jason作者对象
author_obj = models.Author.objects.filter(name='jason').first()
再使用跨表查询
res = author_obj.author_detail
print(res) # 作者详情对象:芜湖
4.查询东方出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
res = publish_obj.book_set # app01.Book.None
res = publish_obj.book_set.all()
print(res) # <QuerySet [<Book: 书籍对象:linux云计算>, <Book: 书籍对象:聊斋志异>]>
5.查询jason编写的书籍
author_obj = models.Author.objects.filter(name='jason').first()
res = author_obj.book_set # app01.Book.None
res = author_obj.book_set.all()
print(res) # <QuerySet [<Book: 书籍对象:golang高并发>, <Book: 书籍对象:python全栈开发>]>
6.查询电话是110的作者
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res) # 作者对象:jason
六.基于对象的跨表查询练习题
"""基于对象的跨表查询本质就是子查询即分步操作即可"""
1.查询数据分析书籍对应的出版社
先获取书籍对象
book_obj = models.Book.objects.filter(title='数据分析').first()
再使用跨表查询
res = book_obj.publish
print(res) # 出版社对象:北方出版社
2.查询python全栈开发对应的作者
先获取书籍对象
book_obj = models.Book.objects.filter(title='python全栈开发').first()
再使用跨表查询
res = book_obj.authors # app01.Author.None
res = book_obj.authors.all()
print(res) # <QuerySet [<Author: 作者对象:jason>, <Author: 作者对象:jerry>]>
3.查询作者jason的详情信息
先获取jason作者对象
author_obj = models.Author.objects.filter(name='jason').first()
再使用跨表查询
res = author_obj.author_detail
print(res) # 作者详情对象:芜湖
4.查询东方出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
res = publish_obj.book_set # app01.Book.None
res = publish_obj.book_set.all()
print(res) # <QuerySet [<Book: 书籍对象:linux云计算>, <Book: 书籍对象:聊斋志异>]>
5.查询jason编写的书籍
author_obj = models.Author.objects.filter(name='jason').first()
res = author_obj.book_set # app01.Book.None
res = author_obj.book_set.all()
print(res) # <QuerySet [<Book: 书籍对象:golang高并发>, <Book: 书籍对象:python全栈开发>]>
6.查询电话是110的作者
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res) # 作者对象:jason
七.双下线查询扩展练习题
"""基于双下划线的跨表查询的结果也可以是完整的数据对象"""
'''手上有条件所在的表可以不被models点 直接点最终的目标数据对应的表'''
1.查询数据分析书籍对应的出版社名称
res = models.Publish.objects.filter(book__title='数据分析')
print(res) # <QuerySet [<Publish: 出版社对象:北方出版社>]>
res = models.Publish.objects.filter(book__title='数据分析').values('name')
print(res) # <QuerySet [{'name': '北方出版社'}]>
2.查询python全栈开发对应的作者姓名和年龄
res = models.Author.objects.filter(book__title='python全栈开发').values('name','age')
print(res) # <QuerySet [{'name': 'jason', 'age': 18}, {'name': 'jerry', 'age': 29}]>
3.查询作者jason的手机号和地址
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','addr')
print(res) # <QuerySet [{'phone': 110, 'addr': '芜湖'}]>
4.查询东方出版社出版的书籍名称和价格
res = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
print(res) # <QuerySet [{'title': 'linux云计算', 'price': Decimal('24888.44')}, {'title': '聊斋志异', 'price': Decimal('16987.22')}]>
5.查询jason编写的书籍名称和日期
res = models.Book.objects.filter(authors__name='jason').values('title','publish_time')
print(res) # <QuerySet [{'title': 'golang高并发', 'publish_time': datetime.date(2022, 6, 7)}, {'title': 'python全栈开发', 'publish_time': datetime.date(2022, 2, 28)}]>
6.查询电话是110的作者的姓名和年龄
res = models.Author.objects.filter(author_detail__phone=110).values('name','age')
print(res) # <QuerySet [{'name': 'jason', 'age': 18}]>
# 连续跨表操作
# 查询python全栈开发对应的作者的手机号
res = models.Book.objects.filter(title='python全栈开发').values('authors__author_detail__phone')
print(res) # <QuerySet [{'authors__author_detail__phone': 110}, {'authors__author_detail__phone': 140}]>
res1 = models.AuthorDetail.objects.filter(author__book__title='python全栈开发').values('phone')
print(res1) # <QuerySet [{'phone': 110}, {'phone': 140}]>
"""
可能出现的不是疑问的疑问:如何获取多张表里面的字段数据
res = models.Book.objects.filter(title='python全栈开发').values('authors__author_detail__phone','authors__name','title')
print(res)
"""
方式1:如果结果集对象是queryset 那么可以直接点query查看
方式2:配置文件固定配置
适用面更广 只要执行了orm操作 都会打印内部SQL语句
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}