ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django路由

2021-06-26 19:33:27  阅读:186  来源: 互联网

标签:name url django urls article path 路由


django视图

官方对于路由分发的介绍:
https://docs.djangoproject.com/zh-hans/3.2/topics/http/urls/

一般使用

路由分发应该在urls.py中进行。默认的根urls是通过settings文件配置的:ROOT_URLCONF = '<项目名>.urls'
路由的分发靠的是urlpatterns列表来的定义的,其内的元素是pathre_path
如:

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

path的一般参数:path('admin/', admin.site.urls, name="myadmin")
admin/是一段字符串,可以直接写成url,也可以带上过滤器,当django自上而下匹配到这个url时,会生成一个HttpRequest对象传给视图的的一个参数。
admin.site.urls是一个视图函数,用于处理请求。
name="myadmin":name参数可以为dango的反向解析,动态生成url提供帮助,和app_name使用效果更好。

关于url以"/"结尾的匹配:如path('admin/', admin.site.urls)可以匹配admin/admin,但若是path('admin', admin.site.urls)的话,就只能匹配到admin

路由转发

通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的urls.py模块中。
要实现这个功能,需要用到django.urls.include模块。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("app1/", include("app1.urls")),
    path("app2/", include("app2.urls")),
]

之后我们就可以在app的urls中做进一步的处理了。
需要注意的是:app.urls中接收到的url是已经去掉匹配部分的。如依照上面的路由,app1/user/index到了app1.urls中时,就剩下了user/index,所以写路由分发时需要注意。而且app中的urls.py需要我们手动创建

转换器

转换器本质上就是一个使用正则表达式匹配url,但是它可以自动将url中匹配的内容转换成我们需要的数据格式传给request,也可以动态生成url。
默认情况下,Django内置下面的路径转换器:

  • str:匹配任何非空字符串,但不含斜杠/,如果你没有专门指定转换器,默认使用该转换器
  • int:匹配0和正整数,返回一个int类型
  • slug:可理解为注释、后缀、附属等概念,是url拖在最后的一部分解释性字符。该转换器匹配任何ASCII字符以及连接符和下划线,比如building-your-1st-django-site;
  • uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用破折号,所有字母必须小写,例如075194d3-6885-417e-a8a8-6c931e272f00。返回一个UUID对象;
  • path:匹配任何非空字符串,重点是可以包含路径分隔符’/‘。这个转换器可以帮助你匹配整个url而不是一段一段的url字符串。要区分path转换器和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:slug>/', views.article_detail),
]

'articles/<int:year>/'中的int是转换器,而year是request中的参数名。

自定义转换器

默认的转换可以实现一般的匹配,但是假如要匹配复杂度和自定义程度比较高的url时,可以自定义一个转换器。

第一步:自定义类
在app中创建一个converters.py,用于放置转换器类

关键实现:

  1. 类属性:regex
    这里需要写正则表达式
  2. 类方法:to_python
    转换数据给视图用,失败要抛出ValueError异常
  3. 类方法:to_url
    返回url供反转操作,失败要ValueError异常
# app/converters.py

class Year:
    regex = "\d{4}"

    def to_python(self, value):
        try:
            return int(value)
        except ValueError:
            raise ValueError

    def to_url(self, value):
        return value

第二步:在url中注册

# polls/urls.py

from django.urls import path, register_converter
from . import views, converters


app_name = "polls"		# app_name的作用后面讲述
# 注册转换器为year_conv
register_converter(converters.Year, "year_conv")

urlpatterns = [
    path("", views.index, name="index"),
	# 和默认转换器一样使用自定义转换器
    path("<year_conv:year>/", views.test, name="test"),
]

关于re_path

Django2.0的urlconf虽然改‘配置方式’了,但它依然向老版本兼容。而这个兼容的办法,就是用re_path()方法。re_path()方法在骨子里,根本就是以前的url()方法,只不过导入的位置变了。下面是一个例子,对比一下Django1.11时代的语法,有什么太大的差别?

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

path()方法的不同点:
捕获URL中的参数使用的是正则捕获,语法是 (?P<name>pattern) ,其中 name 是组名,pattern 是要匹配的模式。
传递给视图的所有参数都是字符串类型。而不像path()方法中可以指定转换成某种类型。在视图中接收参数时一定要小心。

反向解析及应用命名空间

反向解析的功能可以动态生成url,防止我们将url写死,减少维护复杂度。
反向解析可以在python代码中应用,也可以在django的template中应用。

如在urls中这样定义:

from django.urls import path
from .views import index, article
urlpatterns = [
    path("index/", index, name="index"),
    path("article/<int:article_id>", article, name="article")
]
  • python代码中反向解析:

    # 1. 导入django.urls.reverse函数
    # 2. 根据urls中path对象的name参数,确定你要生成的是那个url
    # 3. 假如url中需要参数的话,以args或kwargs传入
    
    
    from django.http import HttpResponse
    from django.urls import reverse
    # Create your views here.
    
    
    def index(request):
    	index_url = reverse("index")
    	return HttpResponse(index_url)
    
    
    def article(request, article_id):
    	# article_url = reverse("article", args=(article_id, ))
    	article_url = reverse("article", kwargs={"article_id": article_id})
    	return HttpResponse(article_url)
    
  • 在template中反向解析:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Title</title>
    </head>
    <body>
    {% url "index" %}
    {% url "article" "1234" %}
    </body>
    </html>

    使用的是django模板引擎的url标签,使用template时,应该要在settings中的INSTALLED_APPS添加上自己的app。

以上只利用path的name参数生成url的做法,在多个app时(如app1:name="index", app2:name="index")可能就不怎么适用了。
因此django为我们提供了一个app_name变量,可以为我们标识不同的app。
在app/urls.py中我们可以自定义一个独一无二的app_name,如:

from django.urls import path
from .views import index, article


app_name = "app01"

urlpatterns = [
    path("index/", index, name="index"),
    path("article/<int:article_id>", article, name="article")
]

在使用的时候只需要在name字符前面加上app_name:即可,如:

article_url = reverse("app01:article", kwargs={"article_id": article_id})

template的使用也是如此,改变第一个参数即可。

django还可以为不同的对象提供标识,实现方式时:给include添加name_space参数。具体可点击:关于includename_space的使用

我的github
我的博客
我的笔记

标签:name,url,django,urls,article,path,路由
来源: https://www.cnblogs.com/lczmx/p/14938791.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有