zoukankan      html  css  js  c++  java
  • day53 url别名反向解析、ORM多表操作、聚合查询、分组查询、F查询、Q查询

    1.url别名反向解析

    2.ORM多表操作

    3.聚合查询

    4.分组查询

    5.F查询

    6.Q查询

    url别名反向解析

    视图部分
    from django.urls import reverse
    print(reverse('book_list')) #/book/list/
    print(reverse('book_edit',args=(2,))) #/book/edit/1/  url的无名分组参数
    print(reverse('book_edit',kwargs={'n': 1,})) #/book/edit/1/ 有名分组参数
    
    return redirect('book_list')
    return redirect(reverse('book_list'))
    
    模板部分  
    无参数的
    <a class="btn btn-primary" href="{% url 'book_add' %}">添加书籍</a>
    # 无名分组参数的
    <a href="{% url 'book_edit' books.id 3 4 %}" class="btn btn-warning">编辑</a>
    # 有名分组
    <a href="{% url 'book_del' books.id %}" class="btn btn-danger">删除</a>
    <a href="{% url 'book_del' n=books.id %}" class="btn btn-danger">删除</a>
    
    urls.py的别名写法如下
    from django.conf.urls import url
    from django.contrib import admin
    
    from app01 import views
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^book/list/', views.book_list, name='book_list'),
        url(r'^book/add/', views.book_add,name='book_add'),
        url(r'^book/edit/(d+)/', views.book_edit, name='book_edit'), # /book/edit/2/
        url(r'^book/del/(?P<n>d+)/', views.book_del,name='book_del'), # /book/edit/2/
    ]
    
    url分发,命名空间
    项目主目录下的urls.py
    from django.conf.urls import url, include
    from django.contrib import admin
    
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        # url(r'^index/', views.index,name='index'),
        url(r'^app01/', include('app01.urls',namespace='app01')),
        url(r'^app02/', include('app02.urls',namespace='app02')),
        #/app01/index/
    ]
    
    app01/urls.py
    from app01 import views
    
    urlpatterns = [
        # /index/
        url(r'^index/', views.index, name='index'),
        url(r'^book/list/', views.book_list, name='book_list'),
        url(r'^book/add/', views.book_add, name='book_add'),
        url(r'^book/edit/(d+)/', views.book_edit, name='book_edit'),  # /book/edit/2/
        url(r'^book/del/(?P<n>d+)/', views.book_del, name='book_del'),  # /book/edit/2/
    ]
    
    app02/urls.py
    from app02 import views
    
    urlpatterns = [
    
        url(r'^index/', views.index, name='index'),
    
    ]
    
    app01/views.py
    def index(request):
        print(reverse('app01:index'))
        # return HttpResponse('app01的路径:' + reverse('index'))
        return HttpResponse('app01的路径:' + reverse('app01:index'))
    
    app02/views.py
    def index(requset):
        print(reverse('app02:index'))
        return HttpResponse('app02的路径: ' + reverse('app02:index'))
    

      

    ORM多表操作

        # 修改
        # 一对一和一对多
        models.Author.objects.filter(name='精华').update(
            name='敬华',
            age=50,
            # ad=models.AuthorDetail.objects.get(id=1),
            ad_id=1,
        )
        # 多对多修改
        obj = models.Book.objects.get(id=2)
        obj.authors.set(['3',]) # 值是字符串,clear + add
    

    查看和执行原生sql

    # 查看原生sql 
    方式1
            from django.db import connection  #通过这种方式也能查看执行的sql语句
            # print(connection.queries)
    	方式2
            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',
                },
            }
        }
    # 执行原生sql
    方式1
            cursor = connection.cursor()
            cursor.execute('select * from app01_book;')
            print(cursor.fetchall())
    
            方式2
                pymysql
        	方式3
            	ret = models.Author.objects.raw('select * from app01_author;') 
                #只限于本表操作
                print(ret)
                for i in ret:
                    print(i.name)

    基于对象的跨表查询

    正向查询和反向查询

    A表关联了B表,关联属性在A表,那么通过A表数据查询B表数据时,叫做正向查询

    正向查询使用 对象.关联属性名称

    反向查询使用 对象.关联模型类名小写

    一对一
    # 正向查询
    # 查看敬华作者的家庭住址
    # select app01_authordetail.addr from app01_author inner join app01_authordetail on app01_author.ad_id app01_atuhordetail.id
    # where app01_author.name='敬华'
    obj = models.Author.objects.get(name='敬华')
    print(obj.ad.addr)   #北京
    # 查询北京协和的作者名称
    # 反向查询
    obj = models.AuthorDetail.objects.get(addr='北京协和')
    print(obj.author.name)
    
    一对多
    查询金鳞岂是池中物这本书的出版社
    正向查询
    obj = models.Book.objects.get(title='金鳞岂是池中物')
    print(obj.publishs.name)
    
    查询马哥出版社出版的书籍有哪些
    反向查询
    ret = models.Publish.objects.get(name='马哥出版社')
    books = ret.book_set.all()  #<QuerySet [<Book: Book object>, <Book: Book object>]>
    
    print(books.values('title'))
    
    多对多
    # 查询虹猫蓝兔七侠传是谁写的
    # select app01_author.name from app01_book inner join app01_book_authors on app01_book.id =
    # app01_book_authors.book_id inner join app01_author on app01_author.id = app01_book_authors.author_id
    
    # 正向查询
    # obj = models.Book.objects.get(title='虹猫蓝兔七侠传')
    # print(obj.authors.all().values('name'))
    
    # 反向查询
    # 查询敬华写了哪些书
    # obj = models.Author.objects.get(name='敬华')
    # print(obj.book_set.all().values('title'))  
    

    基于双下划线的跨表查询

    一对一
    查看敬华作者的家庭住址
    正向写法
    ret =  models.Author.objects.filter(name='敬华').values('ad__addr')
    反向写法
    ret = models.AuthorDetail.objects.filter(author__name='敬华').values('addr')
    print(ret) #<QuerySet [{'addr': '北京'}]>
    
    一对多
    查询金鳞岂是池中物这本书的出版社
    ret = models.Book.objects.filter(title='金鳞岂是池中物').values('publishs__name')
    print(ret) #<QuerySet [{'publishs__name': '小马哥出版社'}]>
    ret = models.Publish.objects.filter(book__title='金鳞岂是池中物').values('name')
    print(ret) #<QuerySet [{'name': '小马哥出版社'}]>
    
    多对多 
    查询虹猫蓝兔七侠传是谁写的
    ret = models.Book.objects.filter(title='虹猫蓝兔七侠传').values('authors__name')
    print(ret)
    ret = models.Author.objects.filter(book__title='虹猫蓝兔七侠传').values('name')
    print(ret) #<QuerySet [{'name': '敬华'}, {'name': '杨浩'}]>
    

      

    聚合查询

    from django.db.models import Avg,Max,Min,Count,Sum
    # 聚合查询
    # ret = models.Book.objects.all().aggregate(Avg('price'))
    # ret = models.Book.objects.all().aggregate(a=Avg('price'),m=Max('price'))
    # print(ret,type(ret)) #{'price__avg': 15.0} <class 'dict'>
    注意结果为字典类型.
    

      

    分组查询

    sql_mode模式

    <https://www.cnblogs.com/clschao/articles/9962347.html>

    # 统计一下每个出版社出版书的平均价格
    # 1.sql查询
    select publishs_id,avg(price) from app01_book group by publishs_id;
    select avg(app01_book.price) from app01_book inner join app01_publish on 
    app01_book.publishs_id = app01_publish.id group by app01_publish.name;
    
    # 2.分组查询
    ret = models.Book.objects.values('publishs_id').annotate(a=Avg('price')) # 方式一
    
    ret = models.Publish.objects.annotate(a=Avg('book__price')) # 方式二
    # <QuerySet [<Publish: Publish object>, <Publish: Publish object>]>
    print(ret.values('a','name'))
    

      

    F查询

    # 查询一下点赞数大于评论数的书籍
    '''1.传统方法'''
    ret = models.Book.objects.all()
    book_list = []
    for i in ret:
    	if i.dianzan > i.comment:
    		book_list.append(i)
    
    '''2.F查询'''
    from django.db.models import F
    ''''针对本表不同字段数据进行对比时或者本表字典做一些统一修改时使用F查询'''
    # 点赞数大于评论数的
    ret = models.Book.objects.filter(dianzan__gt=F('comment'))
    
    '''F查询也支持统一修改'''
    # 所有书籍上调10块
    models.Book.objects.all().update(price=F('price')+10) # 支持四则运算
    

      

    Q查询

    from django.db.models import Q
    '''
    | -- or
    & -- and
    ~ -- not
    '''
    
    '''and与和or或'''
    ret = models.Book.objects.filter(Q(comment__gt=30)|Q(dianzan__gt=50))
    
    ret = models.Book.objects.filter(Q(comment__gt=30)&Q(dianzan__gt=50))
    # 等同于# ret = models.Book.objects.filter(comment__gt=30,dianzan__gt=50)
    
    ret = models.Book.objects.filter(Q(comment__gt=30)|Q(dianzan__gt=50),publishDate__year='2018')
    # 注意没有Q包裹的条件,写在Q包裹的条件后面.并且Q查询和publishyear之间是and的关系
    
    '''Q查询多层嵌套'''
    ret = models.Book.objects.filter(Q(Q(comment__gt=30)|Q(dianzan__gt=50))&Q(xx=11),publishDate__year='2018')
    
    '''条件取反:波浪线写在Q前面'''
    # 取评论数小于等于30 的,或者点赞数大于50的
    ret = models.Book.objects.filter(~Q(comment__gt=30)|Q(dianzan__gt=50))
    

      

  • 相关阅读:
    Java设计模式之单例模式
    sql查询优化整理
    MYSQL 调优学习笔记
    记一次失败的大厂面试
    ElasticSearch 6.3.2 整合 Springboot 2.1.10.RELEASE 版本,使用 Logstash 导入 mysql 数据
    ajax技术实现登录判断用户名是否重复以及利用xml实现二级下拉框联动
    浅谈 KMP 算法
    转载:Docker入门只需看这一篇就够了
    Spring Boot 监听 Activemq 中的特定 topic ,并将数据通过 RabbitMq 发布出去
    hadoop入门之海量Web日志分析 用Hadoop提取KPI统计指标
  • 原文地址:https://www.cnblogs.com/liya1014/p/13693041.html
Copyright © 2011-2022 走看看