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')
原文地址:https://www.cnblogs.com/klw1/p/11269206.html