zoukankan      html  css  js  c++  java
  • Django路由控制

    Django路由控制

    1. Django中路由的作用

    • Django中,url路由的作用,就是将客户端请求的URL,映射到对应的视图函数,并且调用这个视图函数
    • 路由的特点是,从上到下依次匹配,只要匹配上了,就不会再往后匹配
    # urls.py
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^add_publish/', views.add_publish),
    ]
    

    2. 路由简单的正则匹配

    • 路由中的路由路径可以使用正则表达式进行匹配
    urlpatterns = [
        url(r'^test/$',views.test),  # 表示路由路径以test开头,以test/结尾,其他都不可以
        url(r'^test/w+$', views.test), # test后连续的字母数字下划线都可以
    
        # 表示匹配所有,要写在所有路由后,一般用于,跳转到首页或404
        url(r'',views.test)  
    ]
    
    # settings中配置添加,False表示不自动添加斜杠,再带后缀斜杠,就不能匹配了
    APPEND_SLASH=False
    

    3. 无名分组

    • 分组也是正则匹配

    3.1 正则表达式分组举例

    import re
    
    res = re.search('test/([0-9]{4})/([0-9]{2})','test/2018/20')
    print(res.group())
    print(res.group(1))
    print(res.group(2))
    
    test/2018/20
    2018
    20
    

    3.2 利用正则分组接收客户端请求的参数

    • 无名分组,类似于接收实际参数
    # urls.py
    urlpatterns = [
        url(r'^test/([0-9]{4})/([0-9]{2})', views.test),   # 使用分组后,就需要视图函数进行接收函数
        url(r'^test/(d+)', views.test),  # 比如请求中,带有`?nid=1` 这样的参数,直接用正则拿,不用再使用`GET.get()`方式获取了
    ]
    
    # 视图函数test
    def test(request,year,moth):  # 有几个参数,就要接收几个,不然会报错
        print(year)
        print(moth)
        return HttpResponse('OK')
    

    3.2 模拟伪静态网页

    • 伪静态网页,目的就是,让搜索引擎收入SEO权限更高
    • 模拟伪静态网页,利用网页的分组实现,对SEO的网页优化
    # urls.py
    url(r'^test/(d+).html', views.test)   # 客户端请求的是静态地址.html,实际映射到test视图函数
    
    # views.py
    def test(request,id):
        print(id)
        # print(moth)
        return HttpResponse('伪静态'+id+'.html文件')
    
    # 模本
    <a href="/test/?id=2.html">伪静态</a>             # 动态网页
    <a href="/test/{{ book.nid }}.html">伪静态</a> # 转为伪静态网页
    
    

    4. 有名分组

    • 有名分组,类似于接收关键字参数,给正则匹配出来的数据进行命名
    • 有名分组的书写格式:(?P<分组的名字>)

    4.1 正则表达式有名分组举例

    import re
    
    res = re.search('test/(?P<year>[0-9]{4})/(?P<moth>[0-9]{2})','test/2018/20')
    print(res.group('year'))
    print(res.group('moth'))
    
    2018
    20
    

    4.2 有名分组的使用

    • 路由中关键字的名字和视图中关键字的名字,要保持一致,否则报错,视图函数的参数位置可以颠倒
    # urls.py
    url(r'^test/(?P<year>[0-9]{4})/(?P<moth>[0-9]{2})', views.test)
    
    # views.py
    def test(request,year,moth):  # 捕获的分组数据,都是str数字类型
        print(year,moth)
        return HttpResponse('year:%s,moth:%s' %(year,moth))
    
    # 有名分组可以使用`**kwargs`接收,无名分组可以使用`*args`接收,但是有名分组和无名分组不能混用
    def test(request,**kwargs):
        print(kwargs)
        return HttpResponse('%s' %kwargs)
    
    def test(request,*args):
        print(args)
        return HttpResponse('ok')
    

    4.2 设置默认值

    url(r'^test/(?P<year>[0-9]{4})/', views.test)
    def test(request,year,moth=19):   # 在视图中指定默认值
        print(year,moth)
        return HttpResponse('ok')
    

    5. 路由分发

    • 路由分发的顺序:先由总路由分发给各个app,每个app在从自己的urls.py路由中,分发视图函数,或者继续分发到下层的urls.py中,但是不推荐这样

    5.1 在总的路由urls.py中导入include模块,并添加路由

    # urls.py导入include模块
    from django.conf.urls import url,include   
    
    # 添加路由,方式一(推荐)
    url(r'^toapp01',include('app01.urls'))
    
    # 添加路由,方式二
    from app01 import urls
    url(r'^toapp01',include('urls')
    

    5.2 在app01中创建urls.py

    # app01-urls.py
    from django.conf.urls import url,include
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^test01',views.test01)
    ]
    

    6. 反向解析

    • 反向解析:给路由url路径,其个别名
    • 反向解析的作用:用户的使用是根据别名访问的,因此修改路由路径不影响使用

    6.1 反向解析在视图函数中的使用

    # urls.py添加别名
    url(r'^test/', views.test),
    url(r'^index1/', views.index, name='aaa'),   # name=别名,通过访问aaa,反向解析到test
    
    # views视图函数
    def test(request):
        # 映射为路由url路径,即使url路径修改,aaa也能获取到修改后的url
        url=reverse('aaa')
        print(url)
        return redirect(url)   # 重定向到url,这样url重定向就写活了
        # return redirect('/index/')  # 这样就写死了
    
    def index(request):
        return HttpResponse('index')
    

    6.2 反向解析在前端页面中的使用

    # views.py
    def test(request):
        url=reverse('aaa')
        print(url)
        return render(request,'test.html')
    
    # 模板html-test.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--点击后跳转到index,但是这样就写死了,路由index一变化就不能访问了-->
    {#<a href="/index/">页面的反向解析</a>#}
    <!--href="{% url 'aaa' %}"这样就写活了-->
    <a href="{% url 'aaa' %}">页面的反向解析</a>
    </body>
    </html>
    

    6.3 无名分组带参数的反向解析

    # urls.py
    url(r'^test/', views.test),
    url(r'^index/([0-9]{4})/([0-9]{2})', views.index, name='aaa'),
    
    # views.py
    def test(request):
        url=reverse('aaa',args=(2016,12)) # 映射后的参数也要传过来,字符串数字也可以
        print(url)
        return render(request,'test.html')
    
    def index(request,year,month):
        return HttpResponse('index')
    
    # test.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <a href="{% url 'aaa' 2016 11 %}">页面的反向解析</a>  # 页面上需要传参数
    </body>
    </html>
    

    6.4 有名分组带参数的反向解析

    # urls.py
    url(r'^test/', views.test),
    url(r'^index/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', views.index, name='aaa'),
    
    # views.py
    def test(request):
        url=reverse('aaa',kwargs={'year':2012,'month':12})
        # 或者url = reverse('aaa', args=(2012,12))
        print(url)
        return render(request,'test.html')
    
    def index(request,year,month):
        return HttpResponse('index')
    
    # test.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <a href="{% url 'aaa' year=2016 month=11 %}">页面的反向解析</a>
    <a href="{% url 'aaa' 2016 11 %}">页面的反向解析</a>  # 顺序不能颠倒
    </body>
    </html>
    

    7. 名称空间

    • 指定名称空间,表示路由会从指定的名称空间中找
    # urls.py 指定名称空间namespace='app01'
    url(r'^app01/',include('app01.urls',namespace='app01')),
    url(r'^app02/',include('app02.urls',namespace='app02')),
    
    # app01下的urls.py
    from django.conf.urls import url,include
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^test01',views.test01, name='test')  # 指定了相同的别名
    ]
    
    # app02下的urls.py
    from django.conf.urls import url,include
    from django.contrib import admin
    from app02 import views
    
    urlpatterns = [
        url(r'^test02',views.test02, name='test')
    ]
    
    
    # app01下的views.py
    def test01(request):
        # test可以写成app01_test便于区分
        url = reverse('app01:test')  # 表示在路由分发时,只去app01找
        print(url)
        return HttpResponse('app01_test01')
    
    # app02下的views.py
    def test02(request):
        url = reverse('app02:test')  # 别名指定名称空间
        print(url)
        return HttpResponse('app02_test02')
    
    # 模本中的名称空间
    <a href="{% url 'app01:test' %}">html中名称空间的使用</a>
    

    8. Django1.xx版本和Django2.xx版本的区别

    8.1 路由上的区别

    • 1.xx的url和2.xx的re_path一样,2.xx的path不支持正则
    from django.conf.urls import url,include  # 1.xx版本
    from django.conf.urls import re_path,path,include   # 2.xx版本
    
  • 相关阅读:
    mac下更改MySQL的默认编码
    pycharm使用gitlab输错密码解决办法
    Django中form组件的is_valid校验机制
    装饰器整理
    粘包
    MySQL常见数据库引擎及对比
    jtag、在线仿真器
    《如何高效学习》-整体性学习策略
    keil5到iar8的使用配置迁移
    Python3学习(1)——初步了解
  • 原文地址:https://www.cnblogs.com/itone/p/9588060.html
Copyright © 2011-2022 走看看