返回顶部

Django基础二之URL路由系统

一.简介

#循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数执行,就不再往下循环了,并给函数传一个参数request,
和wsgiref的environ类似,就是请求信息的所有内容
urlpatterns = [
     re_path(正则表达式, views视图函数,参数,别名),
]

参数说明 


  • 正则表达式:一个正则表达式字符串
  • views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数
 

二. 正则表达式

from django.views.static import serve
from django.conf import settings
from django.urls import  re_path,path
from blog import views

app_name = 'blog'
urlpatterns = [

    re_path(r'^login/$', views.login, name='login'),
    re_path(r'^get_validcode_img/$', views.get_validcode_img),
    re_path(r'^index/$', views.index, name='index'),
    re_path(r'^register/$', views.register, name='register'),
    re_path(r"^media/(?P<path>.*)$",serve,{"document_root":settings.MEDIA_ROOT}),
    re_path(r'^logout/', views.logout, name='logout'),

    re_path(r'^digg/$', views.digg, name='digg'),

    re_path(r'^(?P<username>\w+)/$', views.home_site, name='home_site'),
    re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>\w+)/$', views.home_site, name='home_site_dis'),
    re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)/$', views.article_detail, name='article_detail')
]

注意事项

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
  3. 不需要添加一个前导的反斜杠(也就是写在正则最前面的那个/),因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  4. 每个正则表达式前面的'r' 是可选的但是建议加上。
  5. ^articles&  以什么结尾,以什么开头,严格限制路径
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True

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

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

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

 

三.分组命名匹配

在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

re_path(r'^(?P<username>\w+)/$', views.home_site, name='home_site'),
re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>\w+)/$', views.home_site, name='home_site_dis'),
re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)/$', views.article_detail, name='article_detail')

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

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

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

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

URL分发

re_path(r'^blog/', include('blog.urls', namespace='blog'))

通过include来进行路由分发,当然blog中要有urls文件,也可以用namespace来设置命名空间,避免不同app有相同视图函数的冲突。

 path转换器

 基本示例

from django.urls import path  
from . import views  
urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<int:year>/', views.year_archive),  
    path('articles/<int:year>/<int:month>/', views.month_archive),  
    path('articles/<int:year>/<int:month>/<slug>/', views.article_detail),  
] 

基本规则:

  • 使用尖括号(<>)从url中捕获值。
  • 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。
  • 无需添加前导斜杠。

Django默认支持以下5个转化器:

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

自定义转换器

对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

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

示例:

class FourDigitYearConverter:  
    regex = '[0-9]{4}'  
    def to_python(self, value):  
        return int(value)  
    def to_url(self, value):  
        return '%04d' % value  

使用register_converter 将其注册到URL配置中:

from django.urls import register_converter, path  
from . import converters, views  
register_converter(converters.FourDigitYearConverter, 'yyyy')  
urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<yyyy:year>/', views.year_archive),  
    ...  
]  

 

四.URL别名和URL反向解析

re_path(r'^login/$', views.login, name='login'),
re_path(r'^index/$', views.index, name='index'),
re_path(r'^register/$', views.register, name='register'),
re_path(r'^logout/', views.logout, name='logout'),
给我的url匹配模式起名(别名)为 login,别名不需要改,路径你就可以随便改了

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

<li><a href="{% url 'blog:login' %}">登录</a></li>
<li><a href="{% url 'blog:register' %}">注册</a></li>

<h5><a href="{% url 'blog:article_detail' username article.pk %}">{{ article.title }}</a></h5>
# 参数之间是空格

# blog代表namespace的名称。如果没有就直接写login

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

return redirect(reverse('blog:login', args=('hello', )))
# 一个保留原搜索条件URL的例子:

def reverse_common_url(self, name, *args, **kwargs):
  name = '%s:%s' % (self.site.namespace, name)
  base_url = reverse(name, args=args, kwargs=kwargs)
  if not self.request.GET:
    url = base_url
  else:
    param = self.request.GET.urlencode()
    query_dict = QueryDict(mutable=True)
    query_dict['_filter'] = param
    url = '%s?%s' % (base_url, query_dict.urlencode())
  return url

 

posted @ 2020-10-08 00:12  muguangrui  阅读(79)  评论(0编辑  收藏  举报