Django之路由层

Django之路由层

一、概述

路由即请求地址与视图函数的映射关系,在Django中路由默认配置在urls.py中。

二、URL配置

URL配置(URLconf)就像Django所支持网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

1 urlpatterns = [
2       url(正则表达式,views视图函数,参数,别名),
3 ]

做个简单的实例:

(1)urls.py文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views #导入模块views.py
urlpatterns= [
    url (r'^admin/', admin.site.urls),
    url (r'^index/',views.index),#新增一条,推荐每一条后加逗号
]

(2)views.py文件

from django.shortcuts import render,HttpResponse #导入HttpResponse,用来生成响应信息

#新增视图函数index
def index(request):
    return HttpResponse("hello world")

测试:

python manage.py runserver 8001 #在浏览器输入:http://127.0.0.1:8001/index  会看到hello world

三、分组

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

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

1.无名分组

(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地址的路径部分为:aarticle/年份,匹配成功的分组部分会以位置参数的形式传给视图哈数,有几个分组就传几个位置参数
    url(r'^article/(\d{4})$',views.article_year),  #无名分组
    
]

(2)views.py文件

from django.shortcuts import render,HttpResponse

#需要额外增加一个形参用于接收传递过来的分组数据
def article_year(request,y):
    return HttpResponse("当前的年份为:%s"%y)

测试:

python manage.py runserver 8001  #在浏览器输入:http://127.0.0.1:8001/article_year/2019   会看到:当前的年份为:2019

2.有名分组

(1)urls.py文件

from django.conf.urls import url
from django.contrib import admin
from blog import views

urlpatterns = [

    url(r'^admin/', admin.site.urls),
    #该正则会匹配url地址的路径部分为:article/年份/月份,匹配成功的分组部分会以关键字参数(year=匹配成功的数字&month=匹配成功的数字)的形式传给视图函数,有几个有名分组就会传几个关键字参数
    url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})',views.article_year_month),  #有名分组

]

(2)views.py文件

from django.shortcuts import render,HttpResponse

#需要额外增加两个形参,形参名必须为year和month
def article_year_month(request,year,month):
    return HttpResponse("当前的年份为%s,月份为%s"%(year,month))

测试:

python manage.py runserver 8001  #在浏览器输入:http://127.0.0.1:8001/article/2019/10 会看到:当前的年份为2019,月份为10

有名分组和无名分组都是为了获取路径中的参数,并传递给视图函数,区别在于无名分组是以位置参数的形式传递,有名分组是以关键字参数的形式传递。无名分组和有名分组不能混合使用。

四、路由分发

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

1.在app01下手动创建urls.py来存放自己的路由

(1)app01下的urls.py文件

from django.conf.urls import url
from app01 import views

urlpatterns = [

    url(r'^article/(\d{4})$',views.article_year),  
  
]

(2)app01下的views.py文件

from django.shortcuts import render,HttpResponse

def article_year(request,y):
    return HttpResponse("当前的年份为:%s"%y)

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

from django.conf.urls import url,include  #导入include
from django.contrib import admin

#总路由表
urlpatterns = [

    url(r'^admin/', admin.site.urls),
    #include函数就是做分发操作的
    url(r'^app01/$',include('app01.urls')),
   
]

测试:

python manage.py runserver 8001  #在浏览器输入:http://127.0.0.1:8001/app01/aarticle/2019 会看到:当前的年份为:2019

五、反向解析

在软件开发初期, url地址的路径设计可能并不完美,后期需要进行调整,如果
项目中很多地方使用了该路径,一旦该路径发生变化,就意味着所有使用该路径
的地方都需要进行修改,这是一个非常繁琐的操作。

解决方案就是在编写一条url时,可以通过参数name为url地址的路径部分起一个别名,项目中就可以通过别名来获取这个路径。以后无论路径如何变化别名与路径始终保持致。

上述方案中通过别名获取路径的过程称为反向解析

我们来实现一个简单的反向解析实例:

(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(r'^register/$',views.register,name="reg"),  #路径register/的别名为reg
    url(r'^login/$',views.register,name="log"),   #路径login/的别名为log
  
]

(2)views.py文件

from django.shortcuts import render,HttpResponse,redirect,reverse  #引入redirect类,用于重定向页面  引入reverse类,用于反向解析

def register(request):

    if request.method=="POST":
        user=request.POST.get("user")
        if user=="alex" and pwd=="123456":
            url = reverse('log')  #reverse会将别名'log'反向解析成路径:/login/
            return redirect(url)   #页面跳转
        return HttpResponse("错误!")
    return render(request,"register.html")  #当不是POST请求时,返回register.html页面,页面中的{% url 'reg' %}会被反向解析成路径:/register/

def login(request):
    name="alex"
    return render(request,"login.html",locals())    

(3)register.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% csrf_token %}   <!--强调:必须加上这一行,而且在开始位置加上-->
    {% load staticfiles %}
    <title>Title</title>
</head>
<body>

<h1>学生注册</h1>
<!--强调:reg必须加上引号-->
<form action="{% url 'reg' %}" method="post"> 
    <p>姓名<input type="text" name="user"></p>
    <p>年龄<input type="text" name="age"></p>
    <p>爱好
        <input type="checkbox" name="hobby" value="1">篮球
        <input type="checkbox" name="hobby" value="2">足球
        <input type="checkbox" name="hobby" value="3">乒乓球
    </p>
    <p><input type="submit">提交</p>


</form>

</body>
</html>

(4)login.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>hello {{ name }}</h1>

<form action="">
    用户名<input type="text">
</form>

</body>
</html>

测试:

python manage.py runserver 8001  #在浏览器输入:http://127.0.0.1:8001/register 会看到登录页面,当用户名输入alex会跳转到login.html

总结:在views.py文件中,反向解析的使用:url=reverse('log'),在模板register.html文件中,反向解析的使用{% url 'reg' %}

注意:当我们项目下创建多个app,每个app下针对匹配的路径起了别名不能重复,否则在反向解析时会出现覆盖。

posted @ 2019-10-22 22:06  流浪代码  阅读(144)  评论(0编辑  收藏  举报