zoukankan      html  css  js  c++  java
  • CSIC_716_2020108【Django入门---模型层】

     

    时间格式的字段

    publish_time = models.DateField() # 年月日

    publish_time = models.DateTimeField() # 年月日 时分秒

    publish_time = models.DateField()  # 年月日
    publish_time = models.DateTimeField()  # 年月日 时分秒
        """
        auto_now:每次修改数据的时候 都会自动将最新的更新时间记录下来
        auto_now_add:只在创建数据的时候将创建时间自动记录下来 之后不会自动改变
        """
    
    用法示例
    publish_time = models.DateField(auto_now=True)  
    publish_time = models.DateTimeField(auto_now_add=True)  
    

      

    单表查询

    queryset对象可以通过 queryset对象.query 可以查看orm语句对应的sql语句

    也可以在django的settings配置文件中加入以下配置,即可查看所有orm操作对应的sql语句

    在Django项目的settings.py文件中,增加的配置内容 :

    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终端打印SQL语句
     必知必会16条
            1.create()  返回值:对象本身
            2.all()     返回值:queryset对象
            3.filter()  返回值:queryset对象
            4.update()   返回值:影响的行数
            5.delete()   返回值:影响的行数
            6.first()   返回值:queryset结果中的对象
            7.last()    返回值:queryset结果中的对象
            8.get()    返回值:对象本身,如果get的对象不存在,就报错
            9.values('field')   返回值:queryset对象,对象中包着{field:value}字典
            10.values_list('field')  返回值:queryset对象,对象中包着(value,)元组
            11.order_by()  返回值:queryset对象; order_by('name')升序;和order_by('-name')降序
            12.count()    返回值:整型,统计queryset中元素的数量
            13.exclude()   返回值:queryset对象
            14.exists()     返回值:布尔型, 用于判断能否根据条件查出queryset对象
            15.reverse()   返回值:queryset对象 ,order_by('name').reverse()等价于order_by('-name')
            16.distinct()  返回值:queryset对象, 去重务必要保证value()中所列的字段完全一致,才能去重
    

      

    双下划线查询

    ****************大于(等于)*******
    __gt=
    __lt=
    __gte=  # greater than equal
    __lte=
    
    ****************范围*******
    __in=[ ,,,]
    __range=( ,)  #包含边界
    
    ***************模糊查询*******
    __contains=‘F’     #严格大小写
    __icontains=‘F’    #忽略大小写   ignorecontains
    

      

      

    ****************对于时间格式的字段****************
    
    fieldname__year=2020  #查询年份是2020的记录
    fieldname__month=12  #查询月份是12的记录
    

      

     当表中有外键的时候,通过ORM增删改查的方法

     这里要知道一个前提条件,外键字段在模型类中如果叫field,到数据库中会自动加一个尾缀_id变成field_id

     在多对多的表关系中,外键虽然建在使用频率较高的表上,但是数据库中,使用频率较高的表中没有外键字段,外键字段实际是出现在多对多生成的第三张表中。

    故在初始化使用频率较高的那张表时,不需要输入多对多外键的值,多对多外键值及其绑定关系需要单独在第三张表中建立。

    模型类中定义的表的操作 

    字段以数据库中的为准   进行新增(多对多外键字段不在此新增)

    #操作数据库对应的字段,一句话直接创建,此时字段以数据库中的为准
    models.Book.objects.create(title='鬼谷子',press_id=4,book_detail_id=2)
    

     

    以模型类中的字段名为准  进行新增(多对多外键字段不在此新增)

    #先获取对象(两种方式获取对象)
    press_obj = models.Company.objects.filter(pk=3).first()  # 一定要从queryset中通过例如 .first()取到对象
    press_obj = models.Company.objects.get(pk=2)  # 或者通过get直接取到对象
    book_detail_obj = models.BookDetail.objects.filter(pk=1).last()
    外键直接等于对象即可,此时的外键不用加尾缀_id,以模型类中的字段名为准
    res1 = models.Book.objects.create(title='诗经', press=press_obj, book_detail=book_detail_obj) 

     查用filter、改用update,方法与上面增类似,也有两种方式。

     

    多对多的情况下衍生出的第三张表的增删改查

     增

    方式一

    author_obj1 = models.Author.objects.get(pk=1)  #取出外键关联的对象
    author_obj2 = models.Author.objects.get(pk=2)  #取出外键关联的对象
    
    book_obj = models.Book.objects.get(pk=1) # 取出外键所在的对象
    
    book_obj.author.add(author_obj1, author_obj2)   #建立绑定关系

    方式二

    book_obj = models.Book.objects.get(pk=2)
    book_obj.author.add(3, 4)  # 直接与作者的id建立绑定关系
    

      

    add专门给第三张关系表添加数据,括号内即可以传数字也可以传对象 并且都支持传多个

    移除绑定关系用remove( , )

    更新绑定关系用set(   ) 括号内一定要构造成可迭代对象(列表或元组)

    清除某个对象外键的绑定关系用 .clear(  )  ,括号内不需要任何参数

    多(跨)表查询

    跨表查询的方式
    1.子查询 将一张表的查询结果当做另外一张表的查询条件
    正常解决问题的思路 分步操作
    2.链表查询
    inner join
    left join
    right join
    union
    建议:在写sql语句或者orm语句的时候 千万不要想着一次性将语句写完 一定要写一点查一点再写一点

    正向查询反向查询的概念:

    正向查询:跨表查询的时候,当外键在当前对象中,去查另一个表的数据时,就是正向查询,正向查询用字段名

    反向查询:跨表查询时,当外键在需要查询的表中时,就是反向查询,反向查询用表名小写

    反向查询时,需要以_set.all()结尾,因为会查到多个结果。

    例如图书与出版社是一对多的关系,即一种图书只能是一个出版社,而一家出版社可以对应多种图书。

    基于对象的跨表查询(正向查询):【子查询】

    先获取对象,在通过外键的字段名,直接以句点符得到外键所在的对象,如果对象可能会有多个的话,要在对象结尾加上 .all()

    基于对象的跨表查询(反向查询):【子查询】

    如果是一对多或者多对多关系,先获取对象,通过外键所在的表名,通过    对象.小写表名_set.all( ) 即可查到结果。

    如果是一对一关系,那么先获取对象,然后   对象.小写表名   就可以查到结果

     基于双下划线的跨表查询:【链表查询】(非常重要

    models.Book.objects.filter(pk=1).values('publish__name') 正向查询
    models.Publish.objects.filter(book__pk=1).values('name') 反向查询
    __也可以连续跨越多张表,再通过__取值
    查到的结果是queryset,即 [{'':''},{'':''}]
    只要表之间有关系 ,就可以通过正向的外键字段或者反向的表名小写 连续跨表操作。

        # 基于双下划线跨表查询(链表查询)
        # 1.查询书籍pk为1的出版社名称
        # models.Book.objects.filter(pk=1).values('publish__name')
        # models.Publish.objects.filter(book__pk=1).values('name')
        # 正向
        # res = models.Book.objects.filter(pk=1).values('publish__name')  # 写外键字段 就意味着你已经在外键字段管理的那张表中
        # print(res)
        # 反向
        # res = models.Publish.objects.filter(book__pk=1)  # 拿出版过pk为1的书籍对应的出版社
        # res = models.Publish.objects.filter(book__pk=1).values('name')
        # print(res)
    
    
        # 2.查询书籍pk为1的作者姓名和年龄
        # res = models.Author.objects.filter(book__pk=1).values(name,author_detail__age)
        # res = models.Book.objects.filter(pk=1).values(author__age,author__author_detail__age)
    
        # 正向
        # res = models.Book.objects.filter(pk=1).values('title','authors__name','authors__age')
        # print(res)
        # 反向
        # res = models.Author.objects.filter(book__pk=1)  # 拿出出版过书籍pk为1的作者
        # res = models.Author.objects.filter(book__pk=1).values('name','age','book__title')
        # print(res)
    
        # 3.查询作者是jason的年龄和手机号
        #
        # models.Author.objects.filter(name='jason').values(age,detail__phone)
        # (models.Author_detail.objects.filter(author__name=jason).values(author__age, phone)
    
        # 正向
        # res = models.Author.objects.filter(name='jason').values('age','author_detail__phone')
        # print(res)
        # 反向
        # res = models.AuthorDetail.objects.filter(author__name='jason')  # 拿到jason的个人详情
        # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age')
        # print(res)
    
        # 查询书籍pk为的1的作者的手机号
    
        # res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
        # print(res)
    
        # res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
        # print(res)
    
        """
        只要表之间有关系  你就可以通过正向的外键字段或者反向的表名小写 连续跨表操作
        """
    重点理解

    (务必掌握折叠的代码)

    聚合查询

     from django.db.models import Max,Min,Avg,Count,Sum

    aggregate ( 聚合函数要给他起个名字 = 关键字(‘fieldname’),支持多个  )

    res = models.Book.objects.aggregate(avg_num=Avg('price'))

    分组查询

      from django.db.models import Max,Min,Avg,Count,Sum

    annotate ( 聚合函数要给他起个名字 = 关键字(‘fieldname’)  )

    分组的总结:  首先明确分组的依据是哪一个类模型,其次通过双下划线查询,结合聚合函数,加上filter筛选和values取值,查出结果。

    1.统计每一本书的作者个数
    res=models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
    
    2.统计出每个出版社卖的最便宜的书的价格
    res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price','book__title')
    
    
    3.统计不止一个作者的图书
    res=models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')
    
    
    4.查询各个作者出的书的总价格
    res=models.Author.objects.annotate(price_sum=Sum('book__price')).values('name','price_sum')
    

     

    自定义分组

     5.如何按照表中的某一个指定字段分组
    res = models.Book.objects.values('price').annotate()  就是以价格分组
    

      

    F与Q查询

    from django.db.models import F , Q

    F('fieldname')  获取字段对应的值

    models.Book.objects.update(price=F('price') + 100)  # 全体价格+100
    
    models.Book.objects.filter(kucun__gt=F('maichu'))  #筛选库存大于卖出
    

      

    Q能够改变查询的条件关系  and or not

    # 名字是python入门and价格是1000的书籍
    models.Book.objects.filter(title='python入门',price=1000)
    
    # 名字是python入门and价格是1000的书籍
    models.Book.objects.filter(Q(title='python入门'),Q(price=1000))  
    
    # 名字是python入门or价格是1000的书籍
    models.Book.objects.filter(Q(title='python入门')|Q(price=1000))  
    
    # 名字(not)不是python入门or价格是1000的书籍
    models.Book.objects.filter(~Q(title='python入门')|Q(price=1000))  
    

      

    Q的高级用法

    #先构造Q类的对象
    q = Q()
    
    #其次定下q对象之间连接时的关系,默认是and,可以按照以下方法调整
    q.connector = 'or'
    
    #然后给q对象增加内容
    q.children.append(('fieldname1','value1'))  # 括号内的元组都是字符串
    q.children.append(('fieldname2','value2'))  # 括号内的元组都是字符串
    
    #写查询语句,筛选条件直接放q
    models.Book.objects.filter(q)  #q类似于   fieldname1=‘value1’  or fieldname2=‘value2’
    

      

  • 相关阅读:
    全程图解】ADSL+笔记本电脑 组建WIFI网络让5800实现WIFI上网(更新完毕)
    JSP用户管理系统【上学应付作业用】
    c++按位操作符
    F#: .NET中的函数编程语言
    Visual Studio OpenGL 配置方法
    Linux下挂载U盘方法
    开发者该以什么为骄傲
    POSIX约定与GNU长选项
    修复移动硬盘"文件或目录损坏且无法读取"
    某国外论坛关于什么是Computer Science的争论,你怎么看?
  • 原文地址:https://www.cnblogs.com/csic716/p/12168678.html
Copyright © 2011-2022 走看看