• day-71Django补充


    orm真实存在的字段名与虚拟字段名

       book_obj = models.Book.objects.filter(pk=1).first()
        book_obj.publish_id = 3          # 点表中真实存在的字段名
        book_obj.save()
    publish_obj
    = models.Publish.objects.filter(pk=2).first() book_obj.publish = publish_obj     # 点orm中字段名 传该字段对应的表的数据对象 book_obj.save()

    orm中既可以使用真实存在字段名来进行增删改查,

    也可以通过虚拟字段后面跟上虚拟字段外键表的数据对象,来进行增删改查,本质这个对象就是外键表数据的id,虚拟字段对应的就是表中的真实字段(如:user_id)

    ORM中对象点的正反查询

                                                          #多对多字段的反向查询
         author_obj = models.Author.objects.filter(name='jason').first()
         print(author_obj.book_set)                          # app01.Book.None
         print(author_obj.book_set.all())
    
                                                              #一对一字段的反向查询
         authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
         print(authordetail_obj.author.name)

    正向查询点虚拟字段名,

    当查询的结果为一个对象时不需要加all()(出现于一对一)

    当查询的结果为多个对象时需要加all(),也就是列表里面套对象,不然会报错(# app01.Author.None)(出现于一对多,多对多)

    反向查询点要查的表名小写

    当查询的结果为一个对象时:

      要查的表名小写,且不需要加all()(出现于一对一)

    当查询的结果为多个对象时:

      要查的表名小写_set.all()),也就是列表里面套对象,不然会报错(# app01.Author.None)(出现于一对多,多对多)

    ORM中双下划线的正反查询

        res = models.Book.objects.filter(title='三国演义').values('authors__authordetail__phone')     #先正向在反向,接着是反向中的列名
         print(res)

    正向查询:

      虚拟字段__虚拟字段对应表的列名

    反向查询:

      表名小写__表中的列名

     ···查询出版社为东方出版社的所有图书的名字和价格
        # 正向
         res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price')
         print(res)
        # 反向
         res = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
         print(res)

    正向查询(思路):

      以出版社为基表查询

    反向查询(思路):

      以书为基表查询

    注意:

      数据的增删改查都是按基表来

      book__price__gt=400(书的价格大于400)

    ORM中聚合查询与分组查询

       # 聚合查询  aggregate
        from django.db.models import Max,Min,Count,Sum,Avg
        # 查询所有书籍的作者个数
         res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors'))
         print(res)
        # 查询所有出版社出版的书的平均价格
         res = models.Publish.objects.aggregate(avg_price=Avg('book__price'))
         print(res) 
        # 统计东方出版社出版的书籍的个数
         res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
         print(res)
    
             #聚合查询:一般用于取值(如多少个数),用法同分组查询
            
        # 分组查询(group_by)   annotate
        # 统计每个出版社出版的书的平均价格
         res = models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')
         print(res)
         
         #统计每一本书的作者个数
         res = models.Book.objects.annotate(count_num=Count('authors')).values('title','count_num')
         
                #这里的authors虚拟字段对应的就是表中的真实字段(authors_id)
                #每一本这样的条件就用分组查询,基表就是书的表,如果没有values默认按基表进行分组,展现出来的是基表中一本书对应的作者个数,如果有values按values进行分组
                #注意分组的时候,Count(),values()里面的是以基表为主
               
         print(res)
         
         #统计出每个出版社卖的最便宜的书的价格
         res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
         
                #这里book__price,也就是统计条件也可以是正反向查询
                
         print(res)
         
        # 查询每个作者出的书的总价格
         res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
         print(res)

     单表查询的补充

      
        res = models.User.objects.exclude(name='jason')             #exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
        
       
        res = models.User.objects.order_by('age').reverse()         #reverse(): 对查询结果反向排序 ( 前面要先有排序才能反向)
        
        
        res = models.User.objects.all().exists()                    # exists(): 如果QuerySet包含数据,就返回True,否则返回False
        res1 = models.User.objects.filter(name='jason',age=3).exists()
        
      
         res = models.User.objects.values('name','age').distinct()  # distinct(): 从返回结果中剔除重复纪录  去重的对象必须是完全相同的数据才能去重
         
         
        # 神奇的双下划线查询
    
        # 查询年轻大于44岁的用户
         res = models.User.objects.filter(age__gt=44)
     
        # 查询年轻小于44岁的用户
         res = models.User.objects.filter(age__lt=44)
     
        # 查询年轻大于等于44岁的用户
         res = models.User.objects.filter(age__gte=44)
    
        # 查询年轻小于等于44岁的用户
         res = models.User.objects.filter(age__lte=44)
    
        # 查询年龄是44或者22或者73的用户
         res = models.User.objects.filter(age__in=[44,22,73])
     
    
        # 查询年龄在22到44范围内
         res = models.User.objects.filter(age__range=[22,44])
    
    
        # 查询名字中包含字母n的用户 
         res = models.Author.objects.filter(name__contains='n')    # sqlite数据库不支持这种查法
      
    
         res = models.User.objects.filter(name__icontains='e')     # 无视大小写
    
    
        # 查询名字以j开头的用户
         res = models.User.objects.filter(name__startswith='j')
    
        # 查询名字以n结尾的用户
         res = models.User.objects.filter(name__endswith='n')
     
        
        # 查询年份
         res = models.Book.objects.filter(publish_date__year=2019)  # sqlite数据库不支持这种查法

     一对多,多对多的增删改补充

    # 一对多的增删改
        #
         models.Book.objects.create(title='红楼梦',price=66.66,publish_id=1)
        
         publish_obj = models.Publish.objects.filter(pk=2).first()
         models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)
    
        # 改(两种方法)   
         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)
    
         book_obj = models.Book.objects.filter(pk=1).first()
         book_obj.publish_id = 3                           # 点表中真实存在的字段名
         book_obj.save()
         publish_obj = models.Publish.objects.filter(pk=2).first()
         book_obj.publish = publish_obj                    # 点orm中字段名 传该字段对应的表的数据对象
         book_obj.save()
    
        # 删(两种放法)
         models.Book.objects.filter(pk=1).delete()
         
         book_obj = models.Book.objects.filter(pk=3).first()
         book_obj.delete()
    
        
        #多对多的增删改
        
        # 增:add支持传数字或对象,并且都可以传多个
        
        #给书籍绑定与作者之间的关系  
        book_obj = models.Book.objects.filter(pk=3).first()
        book_obj.authors.add(1)                             #.authors是拿当前对象跨到第三张多对多表,前面的对象当做表中第一个值
        book_ob j.authors.add(2,3)
        
        author_obj = models.Author.objects.filter(pk=1).first()
        author_obj1 = models.Author.objects.filter(pk=3).first()
        book_obj.authors.add(author_obj)
        book_obj.authors.add(author_obj,author_obj1)
    
        #改(重置):set 可以传数字和对象,并且支持传多个,但传的必须是可迭代对象!!!
        
        # 修改书籍与作者的关系  
         book_obj = models.Book.objects.filter(pk=3).first()
        
        book_obj.authors.set((1,))
        book_obj.authors.set((1,2,3))
        
        author_list = models.Author.objects.all()
        book_obj = models.Book.objects.filter(pk=3).first()
        book_obj.authors.set(author_list)
    
        #删:remove可以传数字和对象,并且支持传多个,如果传的是列表需要打散
        
        # 删除书籍与作者的绑定关系
        book_obj = models.Book.objects.filter(pk=3).first()
        book_obj.authors.remove(1)
        book_obj.authors.remove(2,3)
        
     
         author_list = models.Author.objects.all())
         book_obj.authors.remove(*author_list)         # 需要将queryset打散
    
    
        # 清空 :清空的是你当前这个表记录对应的绑定关系
         book_obj = models.Book.objects.filter(pk=3).first()
         book_obj.authors.clear()

     注:当对象点普通字段时才save(),其他不需要

    补充

            
    模板语法:     
    {%for foo in l %}
        {% if forloop.first %}
            <p>这是第一次</p>
        {% elif forloop.last %}
            <p>这是最后一次</p>
        {% else %}
            <p>{{foo}}</p>
        {% endif %}
    {% emdif %}
         <p>给的是空啊,没法循环</p>
    {% endfor %}
    
    自定义char类型字段:
        class MyCharField(models.Field):
            def __init__(self,max_length,*args,**kwargs):
                self.max_length = max_length
                super().__init__(max_length=max_length,*args,**kwargs)
    
            def db_type(self, connection):
                return 'char(%s)'%self.max_length
    
            
    HTTP响应状态码
        1XX:服务器成功接收到数据正在处理 你可以继续提交数据
        2XX:请求资源成功(200)
        3XX:内部重定向(django里面redirect)(301,302)
        4XX:请求资源不存在(404)
        5XX:服务器内部错误(服务端错误 代码出bug了 服务器机房着火了...500)
        
    
    #url后面不带/,会匹配两次 第一次没匹配上 会让浏览器加一个/再访问一次(默认为trun)
    APPEND_SLASH = True    
    
    
    静态文件路径配置
        settings:
            STATIC_URL=‘/xxx/’
            STATICFILES_DIRS = [
                os.path.join(BASE_DIR,'static'),
            ]
        HTML:
        {% load static %}
        <script src='{% static "myjs.js" %}'></script>
        <link rel="stylesheet" href="{% static 'mycss.css'%}">
        
                        
    反向解析(带参数的)
            
            url(r'^indexxasdaskkdjlasdasdasdasdadasksajdlksaj/(?P<xxx>d+)/', index,name='index'),
            
            有名无名均按照下面方式使用即可
            前端拿到url:{% url 'index' 1 %}
            
            后端拿到url:
            from django.shortcuts import HttpResponse,render,reverse
            def index(request,xxx):
                print(reverse('index',args=(1,))
                return render(request,'test.html')
  • 相关阅读:
    AsyncTask 处理耗时操作&&显示进度条
    AutoCompleteTextView 自定义提示样式
    Android:Error:Execution failed for task ':app:clean'. > Unable to delete directory
    MaterialRefreshLayout+ListView 下拉刷新 上拉加载
    element table 表格 修改背景为透明并去除边框
    vue-element-admin 多层路由问题
    SQLServer 语句相关
    润乾报表
    v-charts
    sql 循环 ,随机数,循环插入一年数据
  • 原文地址:https://www.cnblogs.com/klw1/p/11269206.html
Copyright © 2020-2023  润新知