zoukankan      html  css  js  c++  java
  • Django models.py 模型层(单表多表查询)

    模型层

    如何查询orm语句内部真正的sql语句的两种方式

    1. 如果是queryset对象,可以直接点query查看
    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',
    			},
    		}
    	}
    

    django测试环境的搭建

    import os
    
    if __name__ == "__main__":
                os.environ.setdefault("DJANGO_SETTINGS_MODULE", "one_search.settings")
    			import django
    			django.setup()
    			# 写完以上代码就可以在django测试任何的py文件
    

    单表操作

    方式1:

        models.表名.objects.create(键=值,...)
    

    方式2:

        obj = models.表名(键=值,...)
        obj.save()
    

    方式1:

        models.表名.objects.filter(pk=1).update(键=值,...)
    

    方式2:

        obj = models.表名.objects.filter(pk=1).first()
        obj.键 = 值
        ...
        obj.save()
    

    models.表名.objects.filter(pk=1).delete()
    

    必知必会十三个操作:

    1. all() 查询所有
    res = models.表名.objects.all()
    
    1. filter() 条件查询
    res = models.表名.objects.filter(x=123)
    
    1. get() 查询出对象本身,查不到还会报错,也是条件查询,必须携带参数
    res = models.表名.objects.get(pk=1) 
    
    1. first() 取第一个
    res = models.表名.object.all().first()
    
    1. last() 取最后一个
    res = models.表名.object.all().last()
    
    1. exclude() 取除此之外的,返回满足条件之外的
    res = models.表名.objects.exclude(pk=1)
    
    1. values() 返回列表套字典,参数是字段名,不写参数返回所有的键值
    res = models.表名.objects.values('字段名')
    
    1. values_list() 列表套元组,参数是字段名,不写参数返回所有的值,没有键
    res = models.表名.objects.values_List('字段名')
    
    1. count() 统计数据的个数,没有参数
    res = models.表名.objects.count()
    
    1. distinct() 去重,查询出来所有的字段全都一样才可以去重
    res = models.表名.objects.values('字段名').distinct()
    
    1. order_by() 排序(默认是升序,加负号就是降序)
    res = models.表名.objects.order_by('字段名')
    res = models.表名.objects.order_by('-字段名')
    res = models.表名.objects.order_by('字段名').reverse()
    
    1. reverse() 反转(但是必须是排序好的才可以反转)
    res = models.表名.objects.order_by('字段名').reverse()
    
    1. exists() 判断查询的东西是否存在
    # 简称p用没得
    res = models.表名.objects.filter(pk=123).exists()
    

    神奇的双下滑线查询

    # 查询价格大于200的书籍
    res = models.Book.objects.filter(price__gt=200)
    
    # 查询价格小于200的书籍
    res = models.Book.objects.filter(price__lt=200)
    
    # 查询价格大于等于200的书籍
    res = models.Book.objects.filter(price__gte=200)
    # 查询价格小于等于200的书籍
    res = models.Book.objects.filter(price__lte=200)
    
    # 查询价格是200或者是300或者是400其中的一个
    res = models.Book.objects.filter(price__in=[200, 300, 400])
    // 后面只要是可迭代对象就可以了,也可以写成元组
    
    # 查询价格在200到700之间的书籍
    res = models.Book.objects.filter(price__range=(200,700))
    // 顾头不顾尾
    

    模糊匹配

    就是sql语句中的 like

    # 查询书籍名称中包含p的书籍
    res = models.Book.objects.filter(name__contains='p') // 区分大小写
    res = models.Book.objects.filter(name__icontains='p') // 加个i就不区分大小写了
    
    # 查询书籍名称中以'西'开头的书籍
    res = models.Book.objects.filter(name__startswitch='西')
    # 查询数据名称是以'记'结尾的书籍
    res = models.Book.objects.filter(name__endswitch='记')
    
    # 查询书籍发布日期为2019年的书籍
    res = models.Book.objects.filter(data__year='2019')
    # 查询书籍发布日期为10月的书籍
    res = models.Book.objects.filter(data__month='10')
    

    多表操作

    一对多字段增删改查

    models.表名.objects.create(键=值,外键_id=1)  # 外键_id=1 也可以写成 外键=obj
    

    res = models.表名.objects.filter(pk=1).first
    print(res.外键字段) -> 这个拿到的是对应的对象
    print(res.外键字段_id) -> 这个拿到的是外键字段对应表的id
    

    models.Book.objects.filter(pk=1).update(publish_id=3)
    publish_obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.filter(pk=1).update(publish=publish_obj)
    

    默认是级联删除,所以不要轻易删除数据
    models.表名.objects.filter(pk=1).delete()
    

    分析

    其实一对多的增删改查也就可以把对应的id换成所查询出来的对象,对象默认取得也是id,
    也只是键的不同,键_id对应数字,对应Queryset对象

    多对多字段的增删改查

    # 为主键为3的书籍添加两个作者1,2
    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.add(1,2)
    
    如果两方是多对多关系,有外键的一方可以通过`对象.外键`的方式去设置
    add()括号里面也可以传递对象
    

    修改关系

    # 修改主键为3的书籍作者为2,3
    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.set([2,3])
    
    set()括号里面必须是可迭代对象,里面也是既可以串数字也可以传对象
    

    删除

    # 只删除主键为3的书籍的作者2
    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.remove(2) -> 指定删除
    
    # 删除主键为3的所有对应关系
    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.clear()
    

    多表查询

    ORM跨表查询

    - 子查询
    - 跨表查询
    

    正反向的概念

    - 外键字段在哪里,那个表查被外键关联的表,就是正向
    
    - 谁手里有外键字段 谁就是正向查
    - 没有外键字段就是反向
    
    - 正向查询按字段,反向查询按表名小写
    

    题目是最好的理解方式

    查询书籍是西游记的出版社名称

    1. 方式1(基于对象的跨表查询):
        book_obj = models.Book.objects.filter(name='西游记').first()
        res = book_obj.publish.name # publish是外键
    2. 方式2(连表查询:正向)
        res = models.Book.objects.filter(name='西游记').values('publish__name')
    3. 方式3(连表查询:反向)
        res = models.Pubulish.filter(book_name='西游记').values(name)
    

    查询出版社是上海出版社出版的书籍名称

    1. 方式1(基于对象的跨表查询):
        obj = models.Publish.object.filter(name='上海出版社').first()
        print(obj.book_set)  -> app01.Publish.None 这个并不是没查出来,而是因为他是多个值
        res = obj.book_set.all()
    2. 方式2(连表查询:正向)
        res = models.Book.objects.filter(publish__name='上海出版社').values('name')
    3. 方式3(连表查询:反向)
        res = models.Publish.object.filter(name='上海出版社').values('book__name')
    

    查询书籍id是4的作者的手机号

    1. 方式1(基于对象的跨表查询):
        book_obj = models.Book.objects.filter(pk=4).first()
        res = book_obj.authors.all()
        for i in res:
            author_obj = models.Author.objects.filter(pk=i.id).first()
            print(author_obj.AuthorInfo.tel)
    2. 方式2(连表查询:正向)
        res = models.Book.objects.filter(pk=4).values('authors__AuthorInfo__tel')
        
    3. 方式3(连表查询:反向)
        res = models.AuthorInfo.objects.filter(author__book__id=4).values('tel')
        
    
  • 相关阅读:
    java提高篇(二四)-----HashSet
    链表(线性表)
    逆置线性表(线性表)
    Android布局_表格布局TableLayout
    Android布局_布局概述和LinearLayout布局
    Android_用户界面概述和数据单位
    Android_SDK的常用命令
    Android_程序结构分析
    CSS3_边框属性之圆角的基本图形案例
    CSS3_边框属性之圆角
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11735302.html
Copyright © 2011-2022 走看看