ICode9

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

神奇的双下划线查询、orm创建外键关系、外键字段的增删改查、正反向的概念、多表查询

2022-05-17 23:32:57  阅读:133  来源: 互联网

标签:__ 多表 name models res 外键 查询 filter objects


神奇的双下划线查询

orm创建外键关系

外键字段的增删改查

正反向的概念

多表查询

神奇的双下划线查询

1、大小于
"""
  __gt         大于
  __lt         小于
  __gte        大于等于
  __lte        小于等于
"""
res = models.User.objects.filter(age__gt=20)
res = models.User.objects.filter(age__lt=20)
res = models.User.objects.filter(age__gte=20)
res = models.User.objects.filter(age__lte=20)

2、 __in         成员运算

# 查看年龄是20, 23, 25的用户
res = models.User.objects.filter(age__in=[20, 23, 25])

3、 __range      范围查询
# 查看年龄在10到23之间的用户
res = models.User.objects.filter(age__range=[10,22])

4、包含
"""
    __contains      区分大小写
    __icontains     忽略大小写
"""
# 查找名字中含有o的用户
 res = models.User.objects.filter(name__contains='O')  # <QuerySet []>
    res = models.User.objects.filter(name__icontains='O')  # [<User: 对象:owen>, <User: 对象:oscar>, <User: 对象:tom>]
    
5、开头第一个 __startswith
res = 
models.User.objects.filter(name__startswith='o')  # <User: 对象:owen>, <User: 对象:oscar>

6、最后一个 __endswith
res = models.User.objects.filter(name__endswith='m')  # [<User: 对象:tom>]

7、 正则 __regex
res = models.User.objects.filter(name__regex='^g')  # [<User: 对象:gavin>]

8、 按照年份筛选数据  __year 
res = models.User.objects.filter(register_time__year=2021)

9、 按照月份筛选数据  __month 
res = models.User.objects.filter(register_time__month=5)

orm创建外键关系

"""
关系的种类:
  一对多关系
  多对多关系
  一对一关系
字段的位置
	一对多关系 外键字段建在多的一方
	多对多关系 外键字段建在第三张关系表中
	一对一关系 外键字段建在任意一方都可以 推荐建在查询频率较高的表中
"""
# 一对多关系    ForeignKey
# 多对多关系    ManyToManyField 不需要自己创建表格
# 一对一关系    OneToOneField  建在使用频率高的一方

class Book(models.Model):
    '''图书表'''
    title = models.CharField(max_length=32, verbose_name='书名')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
    publish_time = models.DateField(auto_now_add=True, verbose_name='出版日期')
    # 书与出版社的外键字段    一对多
    publish = models.ForeignKey(to='Publish')  # 默认关联主键
    # 书与作者的外键字段     多对多
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return '书籍对象:%s' % self.title


class Publish(models.Model):
    '''出版社'''
    name = models.CharField(max_length=32, verbose_name='出版社名称')
    add = models.CharField(max_length=64, verbose_name='出版社地址')


    def __str__(self):
        return '出版社对象:%s' % self.name


class Author(models.Model):
    '''作者表'''
    name = models.CharField(max_length=32, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    # 作者与作者详情       一对一关系创建在使用高的一方
    author_detail = models.OneToOneField(to='AuthorDetail')

    def __str__(self):
        return '作者对象:%s' % self.name


class AuthorDetail(models.Model):
    '''作者详情表'''
    phone = models.BigIntegerField(verbose_name='手机号')
    addr = models.CharField(max_length=66, verbose_name='家庭地址')

    def __str__(self):
        return '作者详情对象:%s' % self.addr

外键字段的增删改查

# 一对多、一对一操作
    # 增  两种情况都可以
models.Book.objects.create(title='葵花点穴手', price=9999.00, publish_id=2)
# 第二种,先获取对象,然后添加
    publish_obj = models.Publish.objects.filter(pk=1).first()
    models.Book.objects.create(title='西游记', price=5999.00, publish=publish_obj)
    
# 改
models.Book.objects.filter(pk=2).update(publish_id=3)
# 第二种,先获取队对象
publish_obj = models.Publish.objects.filter(pk=2).first()
   models.Book.objects.filter(pk=1).update(publish=publish_obj)

#多对多字段操作
   	1.第三张关系表创建数据
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.add()
  	'括号内可以放主键值也可以放数据对象 并且都支持多个'
  2.第三张关系表修改数据
  	book_obj.authors.set([5, ])
  '括号内必须是一个可迭代对象 元素同样支持主键值或者数据对象'
  3.第三张关系表删除数据
  	book_obj.authors.remove(4)
    '括号内可以放主键值也可以放数据对象 并且都支持多个'
  4.第三张关系表清空指定数据
  	book_obj.authors.clear()
    '括号内无需传值 直接清空当前表在第三张关系表中的绑定记录'   

正反向的概念

"""
MySQL多表查询思路
	子查询
		将SQL语句用括号括起来当做条件使用
	连表操作
		inner join\left join\right join\union
django orm本质还是使用的上述两种方法
	子查询>>>:基于对象的跨表查询
	连表操作>>>:基于双下划线的跨表查询
"""
核心在于当前数据对象是否含有外键字段,有就是正向,没有则是放向
正向eg:
    由书籍查出版社,外键字段在书籍表中,那么这个就是正向
    由书籍查询作者,外键字段在书籍表中,书查作者就是正向
    由作者查询作者详情,外键字段在作者表中,也是正向
 反向eg:
    由出版社查询书籍,外键字段不在出版社表,那么出版社查书就是方向
# 正反向查询口诀
'''
正向查询按外键字段名
反向查询按表名小写
'''

多表查询

    # 查询葵花点穴手书籍对应的出版社
    # 先获书籍对象
    book_obj = models.Book.objects.filter(title='葵花点穴手').first()
    # 正向查询
    res = book_obj.publish
    print(res)  # 出版社对象: 南京出版社

    # 查询python全栈对应的作者
    # 先获取书籍对象
     book_obj = models.Book.objects.filter(title='python全栈').first()
    # 外键在书,正向查询
     res = book_obj.authors  # app01.Author.None 多对多的关系
     res = book_obj.authors.all()  # [<Author: 作者对象: tom>]
     print(res)

    # 查询作者gavin的详情信息
    # 先获取作者gavin对象
     author_obj = models.Author.objects.filter(name='gavin').first()
    # 外键字段在作者表,正向查询
     res = author_obj.author_detail
     print(res)  # 作者详情对象: 宿州

    # 查询北京出版社出版的书籍
    # 先获取北京出版社对象
     publish_obj = models.Publish.objects.filter(name='北京出版社').first()
    # 外键字段在书籍,所以是反向查询
     res = publish_obj.book_set.all()  # 如果数据多,就使用all
     print(res)  # [<Book: 书籍对象:golang高并发>, <Book: 书籍对象:西游记>]>

    # 查询gavin编写的书籍
    # 先获取作者对象
     author_obj = models.Author.objects.filter(name='gavin').first()
    # 外键字段书籍 方向
     res = author_obj.book_set.all()
     print(res)  # [<Book: 书籍对象:linux云计算>, <Book: 书籍对象:golang高并发>]>

    # 查询电话是222的作者
    # 先获取电话为222的对象
     author_detail_obj = models.AuthorDetail.objects.filter(phone=222).first()
    #  反向查询
     res = author_detail_obj.author
     print(res)  # 作者对象: tom
  • 基于双下划线的跨表查询

"""基于双下划线的跨表查询本质就是连表操作"""
'''手上有什么条件就先拿models点该条件对应的表名'''
# 查询数据分析书籍对应的出版社名称
res = models.Book.objects.filter(title='葵花点穴手').values('publish__name', 'publish__addr')
print(res)  # [{'publish__name': '南京出版社', 'publish__addr': '南京'}]>

    # 查询python全栈对应的作者的年龄和姓名
res = models.Book.objects.filter(title='python全栈').values('authors__name', 'authors__age')
print(res)  # [{'authors__name': 'tom', 'authors__age': 26}]>

    # 查询作者gavin的手机号和地址
res = models.Author.objects.filter(name='gavin').values('author_detail__phone','author_detail__addr')
print(res)  # [{'author_detail__phone': 111, 'author_detail__addr': '宿州'}]>

    #  查询北京出版社出版的书籍名称和价格
res = models.Publish.objects.filter(name='北京出版社').values('book__title','book__price')
print(res)  # [{'book__title': 'golang高并发', 'book__price': Decimal('8989.00')}, {'book__title': '西游记', 'book__price': Decimal('5999.00')}]>

    # 查询tom编写的书籍名称和日期
res = models.Author.objects.filter(name='tom').values('book__title', 'book__publish_time')
print(res)  # [{'book__title': 'python全栈', 'book__publish_time': datetime.date(2022, 2, 28)}, {'book__title': 'linux云计算', 'book__publish_time': datetime.date(2022, 5, 11)}, {'book__title': 'golang高并发', 'book__publish_time': datetime.date(2022, 5, 1)}]>

    # 查询电话是111的作者的姓名和年龄
 res = models.AuthorDetail.objects.filter(phone=111).values('author__name','author__age')
print(res)  # [{'author__name': 'gavin', 'author__age': 29}]>
  • 双下线查询扩展

"""基于双下划线的跨表查询的结果也可以是完整的数据对象"""

'''手上有条件所在的表可以不被models点 直接点最终的目标数据对应的表'''

    # 查询葵花点穴手书籍对应的出版社名称
    res = models.Publish.objects.filter(book__title='葵花点穴手')
    print(res)   # [<Publish: 出版社对象: 南京出版社>]>

    # # 查询python全栈对应的作者的年龄和姓名
    res = models.Author.objects.filter(book__title='python全栈').values('name','age')
    print(res)  # [{'name': 'tom', 'age': 26}]>

    # # 查询作者gavin的手机号和地址
    res = models.AuthorDetail.objects.filter(author__name='gavin').values('phone','addr')
    print(res)  # [{'phone': 111, 'addr': '宿州'}]>

    #  # 查询北京出版社出版的书籍名称和价格
    res = models.Book.objects.filter(publish__name='北京出版社').values('title','price')
    print(res)  # <QuerySet [{'title': 'golang高并发', 'price': Decimal('8989.00')}, {'title': '西游记', 'price': Decimal('5999.00')}]>

    # # 查询tom编写的书籍名称和日期
    res = models.Book.objects.filter(authors__name='tom').values('title','publish_time')
    print(res)  # <QuerySet [{'title': 'python全栈', 'publish_time': datetime.date(2022, 2, 28)}, {'title': 'linux云计算', 'publish_time': datetime.date(2022, 5, 11)}, {'title': 'golang高并发', 'publish_time': datetime.date(2022, 5, 1)}]>

    # # 查询电话是111的作者的姓名和年龄
    res = models.Author.objects.filter(author_detail__phone=111).values('name','age')
    print(res)  # <QuerySet [{'name': 'gavin', 'age': 29}]>
    
    # 连续跨表操作
    # 查询python全栈对应的作者的手机号
    res = models.Book.objects.filter(title='python全栈').values('authors__author_detail__phone')
    print(res)  # [{'authors__author_detail__phone': 222}]>

    res1 = models.AuthorDetail.objects.filter(author__book__title='python全栈').values('phone')
    print(res1)   # [{'phone': 222}]>
  • 如何查看SQL语句
# 方式1:如果结果集对象是queryset 那么可以直接点query查看
res = models.User.objects.values_list('name', 'age')
print(res.query)  # 查看内容封装的SQL语句
SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`

# 方式2:配置文件固定配置
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

标签:__,多表,name,models,res,外键,查询,filter,objects
来源: https://www.cnblogs.com/lsw8898/p/16282899.html

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

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

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

ICode9版权所有