Django笔记11:路由配置详解

配置网站的URL可以说是我们用Django进行网站开发的第一步,Django的路由设置也由原来的1.0版本的正则表达式配置变成了现在2.0版本的路径配置方式,我个人是很喜欢路径配置的方式的,因为这种方式看起来很简洁。接下来我就对路径、正则表达式这两种方式的配置规则做一下整理。

1.路径配置

首先需要在项目或者APP的urls.py中导入path和views,需要注意的是仅仅在APP下定义URL规则是不够的,还需要将此规则导入到项目目录下的urls.py中,下面会讲到。

from django.urls import path
from . import views

然后在urlpatterns这个列表中用刚刚导入的path函数添加我们的URL规则:

urlpatterns = [
    path('', views.index, name='index'),
    path('archives/', views.archives, name="archives"),
    path('post/<int:pk>/', views.article, name="post"),
    path('post/<int:year>/<int:month>/',views.year, name='year')
]

假设我们的网站域名是www.eastnotes.com,那么上面的四条URL规则分别对应如下:

现在我们来看一下path函数的参数:path(route, view, kwargs, name)。可以看出path函数是有四个参数,第一个参数是URL的配置规则,第二个参数是这个URL规则所对应的视图函数或者是include函数,第三个参数是任意个关键字,第四个参数是给此URL规则起一个名字,一般这个名字模板中配合url模板标签来使用。接下来我们将逐一讲解每一个参数:

1.1 route

可以看出这个参数大概可以分为三个部分,第一个部分是单引号,所有的规则必须要在引号内进行编写。第二个部分我把它叫做“激活值”,也就是可以激活该规则对应视图函数的关键字,一般来说我们把它设置为视图函数名,当然,这个关键字和视图函数名不一样可以是可以的。第三个部分就是这个视图函数的参数,是一个可选部分。

当我们在浏览器中输入http://www.eastnotes.com/archieves 的时候,Django的路由将会匹配到第一个URL配置,该配置会对应到视图函数中的archieves函数,可以看出该函数是不需要额外的参数的。

当我们在浏览器中输入http://www.eastnotes.com/post/1 的时候,Django路由将会匹配到第3个URL配置,该配置会对应到视图函数中article函数,可以看到该配置的激活值就和视图函数名不一样,同时该视图函数还需要一个额外的参数,在这里,这个参数是文章的id,是一个整数。那么Django具体是如何来匹配参数的呢?

在配置规则中使用一对尖括号来捕获参数,另外还支持将捕获到的参数的类型进行转换器的转换,比如我们希望id这个参数的类型是int,那么可以这样写:<int:id>,Django2.0新增了5个转化器,分别如下:

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

1.2 view

该参数有两种形式,第一种形式就是view加上某个视图函数名,当浏览器访问第一个参数配置的URL时,此处填写的视图函数就会被执行。第二种形式就是可以写一个include函数,将其他APP的url.py文件导入进来。因为每一个APP下都有一个自己的url.py文件,项目目录下有一个总的url.py,我们常常在项目下的url文件中将各个APP下的URL规则整合到一起。比如在djangblog这个项目下有一个blog APP,我们要将blog/url.py导入到djangoblog/url.py中。

blog/urls.py
urlpatterns = [
    path('blog/', views.blog, name="blog"),
]
djangoblog/urls.py
urlpatterns = [
    path('', include('blog.url')),
]

include函数的参数需要用引号括起来,用 . 将APP的名字(如:blog)和urls.py的文件名url连接起来,如此就将blog APP下的URL配置规则整合到了全站。然后我们在浏览器访问http://www.eastnotes.com/post,就能调用blog APP下面的blog视图函数了。

另外这里需要注意的是,在Djangoblog/urls.py中的配置规则中,path函数的第一个参数我设置为空了,也就是说,在网站根域名后直接写blog APP的激活关键字就可以了,如果第一个关键字为别的,比如:

djangoblog/urls.py
urlpatterns = [
    path('test/', include('blog.url')),
]

那么我们需要在浏览器中输入http://www.eastnotes.com/test/post ,才能够访问到blog视图函数。

1.3 kwargs

此参数是字典形式,可以给视图函数传参数。

1.4 name

1.4.1 在模板中使用URL

name参数的意思是给这个URL起一个别名,起别名的作用就是能够在别的地方用到这个URL(比如:templates中、models中、views等需要做URL跳转的地方)。那我们定义的如下URL规则:

blog/urls.py
urlpatterns = [
    path('post/', views.archives, name="post"),
]

djangoblog/urls.py
urlpatterns = [
    path('', include('blog.url')),
]

如果我们想在一个模板页面中调用这个URL的话,需要用到{% url %}模板标签:

templates/blog/base.html

<a href="{% url 'blog:post' %}" >文章归档</a>

当你点击这个超链接的时候,浏览器就会自动跳转到http://www.eastnotes.com/post 这个页面,需要注意的是url后面应该用引号括起来,中间用冒号: 分开,前面是APP的名字,后面是你在blog/urls.py中定义的name参数值。

1.4.2 在模型中使用URL

考虑这样一个需求,当你点击一篇文章标题时,浏览器会自动跳转到这篇文章的详情页,这个功能该如何实现呢?要实现这个功能,首先我们应该获取到这篇文章的id,通过URL路由将这个id作为参数传入到视图函数中。可是怎样获取到id并传参呢?这时我们需要在模型类中定义一个get_absolute_url的方法,该方法的作用是返回一个该文章的相对URL地址,URL规则还是上面定义的。

blog/models.py
from django.urls import reverse
class Post(models.Model):
    title = models.CharField(max_length100,verbose_name="文章标题")
	
	def get_absolute_url(self):
		return reverse('blog:post',kwargs={'pk':self.pk})

这里用到了reverse函数,它的作用就是反向解析构造url,一般来说需要两个参数,第一个参数可以是我们给URL路由设置的别名,第二个参数是要传递的参数,这个参数我们想让他是文章的id,在模型类中我们可以用self.pk表示这个id。因此reverse会根据文章id返回一个相对的URL连接,比如post/1、post/5、post/6等等。然后我们在模板中这样定义文章标题的a标题的href属性:

<a href="{{ post.get_absolute_url }}">文章标题</a>

在实际的页面中,我们将会得到如下结果:

<a href="/post/1">文章标题</a>
1.4.3 在视图中使用URL

考虑这样一个需求,你需要对一个连接做跳转,即点击某一个超链接,浏览器会跳转到别的链接这样的功能。该如何实现呢?这时我们就需要在视图函数中用到reverse函数了:

URL配置如下:

blog/urls.py
urlpatterns = [
    path('old/',views.old,name="old_page"),
    path('new/',views.new,name="new_page"),
]

原来的视图函数:

from django.shortcuts import HttpResponse
def old(request):
    return HttpResponse('这是一个old_page')

def new(request):
    return HttpResponse('这是一个new_page')

当我们访问http://www.eastnotes.com/old 的时候,会得到字符串:这是一个old_page,当我们访问http://www.eastnotes.com/new 的时候,会得到字符串:这是一个new_page。现在我想在浏览器输入http://www.eastnotes.com/old 的时候自动跳转到http://www.eastnotes.com/new 这个链接应该如何实现呢?现在我们将old这个视图函数做如下改变:

from django.shortcuts import HttpResponse,HttpResponseRedirect
def old(request):
    return HttpResponse(reverse('blog:new_page'))

def new(request):
    return HttpResponse('这是一个new_page')
  1. 我们导入了一个HttpResponseRedirect函数,该函数可以实现重定向
  2. 我们在HttpResponseRedirect这个函数中写了一个reverse函数,参数就是我们定义的那个新的页面的URL模式的别名

经过这两个改进,我们就实现了页面的跳转了。

2. 使用正则

虽然说Django2.0改进了URL路由的设置方式,但仍然保留了老版的正则设置方式,要想使用正则的话需要使用另外一个函数:re_path,下面只举几个例子,不做详细介绍。

from django.urls import path, re_path
from . import views
urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    re_path('articles/(?P<year>[0-9]{4})/', views.year_archive),
    re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive),
    re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[^/]+)/', views.article_detail),
]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值