django_正反向查询

一.双下划线查询

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',
        },
    }
}
posted @ 2022-05-17 23:45  笑舞狂歌  阅读(256)  评论(0编辑  收藏  举报