ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django_正反向查询

2022-05-18 00:05:10  阅读:143  来源: 互联网

标签:__ obj 正反 models res 查询 book objects 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',
        },
    }
}

标签:__,obj,正反,models,res,查询,book,objects,django
来源: https://www.cnblogs.com/xwkg/p/16282962.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有