• Django的路由层


    Django的路由层

    URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。

    你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

    urls

    一、URLconf配置

    基本格式:

    from django.conf.urls import url
    from app import views
    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
    ]
    

    参数说明:

    • 正则表达式: 一个正则表达式字符串,例如url地址为:http://127.0.0.1:8000/index/,正则表达式要匹配的部分是index/
    • views视图函数: 一个可以调用对象,通常为一个视图函数或一个指定视图函数路径的字符串,用来处理业务逻辑
    • 参数:可选,要传递给函数的默认参数(字典形式)
    • 别名:一个可选的name参数,用于反向解析

    二、正则表达式配置

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^articles/2003/$', views.special_case_2003),
        url(r'^articles/([0-9]{4})/$', views.year_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
        url(r'',views.errors)  # 404页面
    ]
    

    说明:

    • urlpatterns中的元素url匹配规则安装从上到下逐一匹配正则表达式,一旦匹配成功则不再继续往下寻找
    • 若要想从url中获取其中的值,只需要在他周围放置圆括号(分组匹配),并且相对应的视图函数需要设置形参接收数据
    • 不需要添加一个前导的反斜杠,因为每个URL都有,例如:应该是^articles 而不是 ^/articles。。
    • 在浏览器请求数据时候,在浏览器中url,Django会在后面默认添加反斜杠,在settings中可以配置控制url后面是否自动增加斜杠(APPEND_SLASH = False 默认是True 自动加斜杠)
    • 每个正则表达式前面 'r'是可选,建议加上,作用取消转义字符的含义。
    • 在浏览器中请求数据中.html,可是修改正则表达式为 acticles.html
    # 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
    APPEND_SLASH=True # 默认是True 自动加斜杠
    

    Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。

    其效果就是:

    我们定义了urls.py:

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
            url(r'^blog/$', views.blog),
    ]
    

    访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/

    如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。

    三、分组命名匹配

    什么是分组、为何要分组呢?比如我们开发了一个博客系统,当我们需要根据文章的id查看指定文章时,浏览器在发送请求时需要向后台传递参数(文章的id号),可以使用 http://127.0.0.1:8000/article/?id=3,也可以直接将参数放到路径中http://127.0.0.1:8001/article/0/,获取id的值

    针对后一种方式Django就需要直接从路径中取出参数,这就用到了正则表达式的分组功能了,分组分为两种:无名分组与有名分组

    3.1无名分组

    #urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        
        # 下述正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数
        url(r'^aritcle/(d+)/$',views.article), 
    ]
    
    # views.py
    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    # 需要额外增加一个形参用于接收传递过来的分组数据
    def article(request,article_id):
        return HttpResponse('id为 %s 的文章内容...' %article_id)
    

    python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8000/article/3/ 会看到: id为 3 的文章内容...

    无名分组总结:

    • 使用方式:url(r'^test/(d+)/', views.index)

      无名分组url(r'^test/(d+)/', views.index)会将括号内匹配到的内容当做 位置参数 传递给后面的视图函数index(request,args)

    • 浏览器没有携带数字,则会报错,浏览器出现大黄页

    • 有几个分组,要有几个位置参数接收

    3.2 有名分组

    # urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        
        # 该正则会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=匹配成功的数字)的形式传给视图函数,有几个有名分组就会传几个关键字参数
        url(r'^aritcle/(?P<article_id>d+)/$',views.article), 
    ]
    
    # views.py
    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    # 需要额外增加一个形参,形参名必须为article_id
    def article(request,article_id):
        return HttpResponse('id为 %s 的文章内容...' %article_id)
    

    python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8000/article/3/ 会看到: id为 3 的文章内容...

    url(r'^test/(d+)/(d+)/', views.test),
    url(r'^test/(?P<xxx>d+)/(?P<month>d+)/', views.test),
    url(r'^test_addsajdsjkahdkjasjkdh/(d+)/', views.testadd),
    url(r'^test_addsajdsjkahdkjasjkdh/(?P<year>d+)/', views.testadd),
    

    有名分组总结:

    • 使用方式: url(r'/index/(?P<user_id>d+)/', views.index)

      有名分组,url(r'^index/(?P<user_id>d+)/', views.index),会将括号内匹配到的内容当做 关键字参数 传递给后面的视图函数index(request,month=123)

    • 有名分组的名字,必须和对应的视图函数中参数名相同

    • 浏览器没有携带数字,则会报错,浏览器出现大黄页

    • 有几个有名分组,就要有几个形参接收

    3.3 无名分组和有名分组总结

    • 有名分组和无名分组都是为了获取路径中的参数,并传递给视图函数;

    • 区别在于无名分组是以位置参数的形式传递,有名分组是以关键字参数的形式传递;

    • 有名无名单独使用的情况下 可以用多个

    • 强调:无名分组和有名分组不要混合使用

    URLconf匹配的位置

    URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。

    例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/。

    在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/

    URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POSTGETHEAD等等 —— 都将路由到相同的函数。

    捕获的参数永远都是字符串

    每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    

    传递到视图函数views.year_archive() 中的year 参数永远是一个字符串类型。

    四、反向解析

    随着项目功能的增加,app会越来越多,路由也越来越多,每个app都会有属于自己的路由,如果再将所有的路由都放到一张路由表中,会导致结构不清晰,不便于管理,所以我们应该将app自己的路由交由自己管理,然后在总路由表中做分发
    根据某一个东西 动态解析出一个结果 该结果可以直接访问对应的url,反向解析

    Django 提供一个办法是让URL 映射是URL 设计唯一的地方。你填充你的URLconf,然后可以双向使用它:

    • 根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
    • 根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。

    第一种方式是我们在前面的章节中一直讨论的用法。第二种方式叫做反向解析URL、反向URL 匹配、反向URL 查询或者简单的URL 反查。
    在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:

    • 在模板中:使用url模板标签。
    • 在Python 代码中:使用django.core.urlresolvers.reverse() 函数。
    • 在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。

    上面说了一大堆,你可能并没有看懂。(那是官方文档的生硬翻译)。

    咱们简单来说就是可以给我们的URL匹配规则起个名字,一个URL匹配模式起一个名字。

    这样我们以后就不需要写死URL代码了,只需要通过名字来调用当前的URL。

    举个简单的例子:

    url(r'^index/', views.index, name='app1.index') # 给我的url匹配模式起名为app1.index
    url(r'^home/(d*)', views.index, name='home'),  # 给我的url匹配模式起名为index
    

    在模板里面可以这样引用:

    {% url 'app1.index' %}
    <a href="{% url 'app1.index' %}">反向解析</a>
    

    在views函数中可以这样引用:

    from django.shortcuts import  reverse
    def index(request):
       
        print(reverse('app1.index')) # /index/
    
        return render(request, 'index.html')
    

    案例:登录成功跳转到index.html页面

    # url.py
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        
        url(r'^login/$', views.login,name='login_page'), # 路径login/的别名为login_page
        url(r'^index/$', views.index,name='index_page'), # 路径index/的别名为index_page
    ]
    
    # views.py
    from django.shortcuts import render 
    from django.shortcuts import reverse # 用于反向解析
    from django.shortcuts import redirect #用于重定向页面
    from django.shortcuts import HttpResponse
    
    def login(request):
        if request.method == 'GET':
            # 当为get请求时,返回login.html页面,页面中的{% url 'login_page' %}会被反向解析成路径:/login/
            return render(request, 'login.html')
        
        # 当为post请求时,可以从request.POST中取出请求体的数据
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        if name == 'kevin' and pwd == '123':
            url = reverse('index_page')  # reverse会将别名'index_page'反向解析成路径:/index/       
            return redirect(url) # 重定向到/index/
        else:
            return HttpResponse('用户名或密码错误')
    
    
    def index(request):
        return render(request, 'index.html')
    
    <!--login -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面</title>
    </head>
    <body>
    <!--强调:login_page必须加引号-->
    <form action="{% url 'login_page' %}" method="post">
        {% csrf_token %} <!--强调:必须加上这一行,后续我们会详细介绍-->
        <p>用户名:<input type="text" name="name"></p>
        <p>密码:<input type="password" name="pwd"></p>
        <p><input type="submit" value="提交"></p>
    
    </form>
    </body>
    </html>
    
    <!--index -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <h3>我是index页面...</h3>
    </body>
    </html>
    
    # 在浏览器输入:http://127.0.0.1:800/login/ 会看到登录页面,输入正确的用户名密码会跳转到index.html
    # 当我们修改路由表中匹配路径的正则表达式时,程序其余部分均无需修改
    

    4.1 有名分组与反向解析连用·

    举个简单的例子:

    # 有名分组和反向解析
    url(r'^index/(?P<user_id>d+)/', views.index, name='app1.index')
    

    在模板里面可以这样引用:

    <a href="{% url 'app1.index' 4  %}">反向解析</a>
    

    在views函数中可以这样引用:

    from django.shortcuts import  reverse
    def index(request, user_id):
        # 有名分组和反向解析连用,
    
        print(user_id)
        print(reverse('app1.index', args=(user_id,))) # /index/4/
    
        return render(request, 'index.html')
    
    <!-- home -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <a href="{% url 'app1.index' 4%}">反向解析</a>
    </body>
    </html>
    

    注意: 反向解析的别名 一定不要重复

    五、路由分发(******)

    随着项目功能的增加,app会越来越多,路由也越来越多,每个app都会有属于自己的路由,如果再将所有的路由都放到一张路由表中,会导致结构不清晰,不便于管理,所以我们应该将app自己的路由交由自己管理,然后在总路由表中做分发,具体做法如下

    # 创建app01和app02
    python3 manage.py startapp app01
    python3 manage.py startapp app02
    

    django里面的app可以有自己的static文件,templates文件夹,urls.py(******) ,需要手动创建

    项目名下面的urls.py不再做路由与视图函数对应关系, 而是做一个中转站 只负责将请求分发到不同的app中 , 然后在app的urls.py完成路由与视图函数的对应关系

    # app01
    # urls.py
    from django.conf.urls import url
    from app import views
    
    urlpatterns = [
        url(r'^index/', views.index, name='app1.index')
    ]
    
    # views.py 
    from django.shortcuts import render, HttpResponse,
    def index(request):
        # 路由分发
        return HttpResponse("我是app1下面的index")
    
    # app01
    # urls.py
    from django.conf.urls import url
    from app02 import views
    
    urlpatterns = [
        url(r'^index/', views.index, name='app2.index')
    ]
    
    
    # views.py 
    from django.shortcuts import render, HttpResponse
    # Create your views here.
    def index(request):
        return HttpResponse("我是app2下面的index")
    
    # 项目下的urls.py
     rom django.conf.urls import url,include
    from django.contrib import admin
    from app  import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^$', views.home),
        # 给路由与视图函数对应关系 起一个别名  后续根据这个别名 就能够动态解析出所对应的url
        # 第一种:麻瓜式
        url(r'^app/', include('app.urls')),
        url(r'^app02/', include('app02.urls'))
        
        # 第二种 名称空间
        # url(r'^app/', include('app.urls', namespace="app01")),
        # url(r'^app02/', include('app02.urls', namespace='app02'))
    ]
    
    
    # python manage.py runserver 8001  
    # 在浏览器输入:http://127.0.0.1:8001/app/index/ 会看到:我是app1下面的index
    # 在浏览器输入:http://127.0.0.1:8001/app02/index/ 会看到:我是app2下面的index
    

    六、名称空间

    当我们的项目下创建了多个app,并且每个app下都针对匹配的路径起了别名,如果别名存在重复,那么在反向解析时则会出现覆盖,如下

    1 创建两个app

    
    # 创建app01和app02
    python3 manage.py startapp app01
    python3 manage.py startapp app02
    

    2 在每个app下手动创建urls.py来存放自己的路由,并且为匹配的路径起别名

    app01下的urls.py文件

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        # 为匹配的路径app01/index/起别名'index_page'
        url(r'^index/$',views.index,name='index_page'), 
    ]
    

    app02下的urls.py文件

    from django.conf.urls import url
    from app02 import views
    
    urlpatterns = [
        # 为匹配的路径app02/index/起别名'index_page',与app01中的别名相同
        url(r'^index/$',views.index,name='index_page'), 
    ]
    

    3 在每个app下的view.py中编写视图函数,在视图函数中针对别名'index_page'做反向解析

    app01下的views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    from django.shortcuts import reverse
    
    def index(request):
        url=reverse('index_page')
        return HttpResponse('app01的index页面,反向解析结果为%s' %url)
    

    app02下的views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    from django.shortcuts import reverse
    
    def index(request):
        url=reverse('index_page')
        return HttpResponse('app02的index页面,反向解析结果为%s' %url)
    

    3 在总的urls.py文件中(mysite2文件夹下的urls.py)

    from django.conf.urls import url,include
    from django.contrib import admin
    
    # 总路由表
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        
        # 新增两条路由,注意不能以$结尾
        url(r'^app01/', include('app01.urls')),
        url(r'^app02/', include('app02.urls')),
    ]
    

    4、测试:

    python manage.py runserver 8001  
    

    在测试时,无论在浏览器输入:http://127.0.0.1:8000/app01/index/还是输入http://127.0.0.1:8000/app02/index/ 针对别名'index_page'反向解析的结果都是/app02/index/,覆盖了app01下别名的解析。

    解决这个问题的方法之一就是避免使用相同的别名,如果就想使用相同的别名,那就需要用到django中名称空间的概念,将别名放到不同的名称空间中,这样即便是出现重复,彼此也不会冲突,具体做法如下

    1、总urls.py在路由分发时,指定名称空间

    from django.conf.urls import url, include
    from django.contrib import admin
    
    # 总路由表
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        
        # 传给include功能一个元组,元组的第一个值是路由分发的地址,第二个值则是我们为名称空间起的名字
        url(r'^app01/', include(('app01.urls','app01'))),
        url(r'^app02/', include(('app02.urls','app02'))),
    ]
    

    2、修改每个app下的view.py中视图函数,针对不同名称空间中的别名'index_page'做反向解析

    app01下的views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    from django.shortcuts import reverse
    
    def index(request):
        url=reverse('app01:index_page') # 解析的是名称空间app01下的别名'index_page'
        return HttpResponse('app01的index页面,反向解析结果为%s' %url)
    

    app02下的views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    from django.shortcuts import reverse
    
    def index(request):
        url=reverse('app02:index_page') # 解析的是名称空间app02下的别名'index_page'
        return HttpResponse('app02的index页面,反向解析结果为%s' %url)
    

    3、测试:

    python manage.py runserver 8001  
    

    浏览器输入:http://127.0.0.1:8001/app01/index/反向解析的结果是/app01/index/

    在浏览器输入http://127.0.0.1:8001/app02/index/ 反向解析的结果是/app02/index/

    总结+补充

    1、在视图函数中基于名称空间的反向解析,用法如下
    url=reverse('名称空间的名字:待解析的别名(name)')
    
    2、在模版里基于名称空间的反向解析,用法如下
    <a href="{% url '名称空间的名字:待解析的别名'%}">哈哈</a>
    

    七、伪静态

    • 在浏览器中请求数据中.html,可是修改正则表达式为 acticles.html(将动态网页假装成静态)
    • 这样做的目的是为了提高搜索引擎的SEO查询优先级,搜索在收录网站的时候 会优先收录看上去像是静态文件的资源

    八、虚拟环境

    • 通常针对不同的项目 只会安装该项目所用的模块 用不到的一概不装
    • 不同的项目有专门的解释器环境与之对应
    • 每创建一个虚拟环境 就类似于重新下载了一个纯净的python解释器
    • 虚拟环境不要创建太多个

    九、django2.0版与1.x的区别

    1554197031700

    9.1 re_path

    Django2.0中的re_path(需要导入)与django1.0的url一样,传入的第一个参数都是正则表达式

    from django.urls import re_path # django2.0中的re_path
    from django.conf.urls import url # 在django2.0中同样可以导入1.0中的url
    
    urlpatterns = [
        # 用法完全一致
        url(r'^app01/', include(('app01.urls','app01'))),
        re_path(r'^app02/', include(('app02.urls','app02'))),
    ]
    

    9.2 path

    在Django2.0中新增了一个path功能,用来解决:数据类型转换问题与正则表达式冗余问题,如下

    urls.py文件

    from django.urls import re_path
    
    from app01 import views
    
    urlpatterns = [
        # 问题一:数据类型转换
        # 正则表达式会将请求路径中的年份匹配成功然后以str类型传递函数year_archive,在函数year_archive中如果想以int类型的格式处理年份,则必须进行数据类型转换
        re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    
        # 问题二:正则表达式冗余
        # 下述三个路由中匹配article_id采用了同样的正则表达式,重复编写了三遍,存在冗余问题,并且极不容易管理,因为一旦article_id规则需要改变,则必须同时修改三处代码
        
        re_path(r'^article/(?P<article_id>[a-zA-Z0-9]+)/detail/$', views.detail_view),
        re_path(r'^articles/(?P<article_id>[a-zA-Z0-9]+)/edit/$', views.edit_view),
        re_path(r'^articles/(?P<article_id>[a-zA-Z0-9]+)/delete/$', views.delete_view),
    ]
    

    views.py

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    def year_archive(request,year):
        print(year,type(year))
        return HttpResponse('year_archive page')
    
    def detail_view(request,article_id):
        print(article_id, type(article_id))
        return HttpResponse('detail_view page')
    
    def edit_view(request,article_id):
        print(article_id, type(article_id))
        return HttpResponse('edit_view page')
    
    def delete_view(request,article_id):
        print(article_id, type(article_id))
        return HttpResponse('delete_view page')
    

    1554197083806

    Django2.0中的path如何解决上述两个问题的呢?请看示例

    from django.urls import path,re_path
    
    from app01 import views
    
    urlpatterns = [
        # 问题一的解决方案:
        path('articles/<int:year>/', views.year_archive), # <int:year>相当于一个有名分组,其中int是django提供的转换器,相当于正则表达式,专门用于匹配数字类型,而year则是我们为有名分组命的名,并且int会将匹配成功的结果转换成整型后按照格式(year=整型值)传给函数year_archive
    
    
        # 问题二解决方法:用一个int转换器可以替代多处正则表达式
        path('articles/<int:article_id>/detail/', views.detail_view), 
        path('articles/<int:article_id>/edit/', views.edit_view),
        path('articles/<int:article_id>/delete/', views.delete_view),
    ]
    

    强调:

    #1、path与re_path或者1.0中的url的不同之处是,传给path的第一个参数不再是正则表达式,而是一个完全匹配的路径,相同之处是第一个参数中的匹配字符均无需加前导斜杠
    
    #2、使用尖括号(<>)从url中捕获值,相当于有名分组
    
    #3、<>中可以包含一个转化器类型(converter type),比如使用 <int:name> 使用了转换器int。若没有转化器,将匹配任何字符串,当然也包括了 / 字符
    

    img

    django默认支持一下5种转换器(Path converters)

    str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    int,匹配正整数,包含0。
    slug,匹配字母、数字以及横杠、下划线组成的字符串。
    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
    

    例如

    path('articles/<int:year>/<int:month>/<slug:other>/', views.article_detail) 
    # 针对路径http://127.0.0.1:8000/articles/2009/123/hello/,path会匹配出参数year=2009,month=123,other='hello'传递给函数article_detail
    

    很明显针对月份month,转换器int是无法精准匹配的,如果我们只想匹配两个字符,那么转换器slug也无法满足需求,针对等等这一系列复杂的需要,我们可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

    • regex 类属性,字符串类型
    • to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
    • to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

    自定义转换器示例:

    1. 在app01下新建文件path_ converters.py,文件名可以随意命名

      class MonthConverter:
          regex='d{2}' # 属性名必须为regex
      
          def to_python(self, value):
              return int(value)
      
          def to_url(self, value):
              return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
      
    2. 在urls.py中,使用register_converter 将其注册到URL配置中:

      from django.urls import path,register_converter
      from app01.path_converts import MonthConverter
      
      register_converter(MonthConverter,'mon')
      
      from app01 import views
      
      
      urlpatterns = [
          path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),
      
      ]
      
    3. views.py中的视图函数article_detail

      from django.shortcuts import render,HttpResponse,reverse
      
      def article_detail(request,year,month,other):
          print(year,type(year))
          print(month,type(month))
          print(other,type(other))
          print(reverse('xxx',args=(1988,12,'hello'))) # 反向解析结果/articles/1988/12/hello/
          return HttpResponse('xxxx')
      
    4. 测试

      # 1、在浏览器输入http://127.0.0.1:8000/articles/2009/12/hello/,path会成功匹配出参数year=2009,month=12,other='hello'传递给函数article_detail
      # 2、在浏览器输入http://127.0.0.1:8000/articles/2009/123/hello/,path会匹配失败,因为我们自定义的转换器mon只匹配两位数字,而对应位置的123超过了2位
      
    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    RAID卡 BBU Learn Cycle周期的影响
    Linux下查看Raid磁盘阵列信息的方法
    ROS导航包的介绍
    ROS源码解读(二)--全局路径规划
    ROS源码解读(一)--局部路径规划
    VS运行release版本正常,直接执行exe文件会出现问题
    IFM设备 Linux方面资料
    Map-making Robots: A Review of the Occupancy Grid Map Algorithm
    Eigen 介绍及简单使用
    绘制二维障碍栅格地图
  • 原文地址:https://www.cnblogs.com/randysun/p/11746811.html
Copyright © 2020-2023  润新知