URL配置与命名空间

发布于 2019-10-25 17:50:26   阅读量 162  点赞 0  

1.路由函数:path(),re_path()函数

  re_path()与path()的作用都是一样的,不过re_path在写url的时候可以使用正则表达式,功能更加强大。

  • 使用 re_path() 与正则表达式的时候,推荐的hi用原生字符串;在url字符串前加‘r’,其不会进行转>>移,也不会将< >包裹的字符串作为参数,而此时若需传递参数,则应以 (?P<arg>) 的形式传入。

  • 如无特殊要求,直接使用 path() 就够了,省得使用晦涩的正则表达式;除非url中涉及到复杂的匹配模式。

详解:path()函数的定义为:path(route,view,name=None,kwargs=None)

① route:url的匹配规则。在该参数中可以通过尖括号<>指定url中需要传递的参数,(如访问文章时的id);且在传递参数的时候,可以指定参数的类型(详见URL转换器)。

② view:可为一个视图函数、类视图.as_view、或是django.urls.include()函数的返回值。

③ name:url命名。

④ kwargs:给视图函数传递的额外的参数,该参数接收一个字典,传到视图函数中。  

URL转换器(convert)

(若无指定转换器,则默认使用str转换器)

  • str:不含斜杠'/ '的字符串
  • int:数字
  • path:同str都是字符串,但可包含斜杠
  • uuid:格式确定的,唯一的一串字符串
  • slug:只含英文中的横杠、英文字符、阿拉伯数字、下划线的字符串

2.URL模块化

随着项目的变大,url会变得越来越多,所有url都放在项目的urls.py中会导致过于臃肿。因此将每个app的url放在各自的urls.py中,用以存储与本app相关的子url。

*用法:*

    path('~',include(~)),
  • 使用include()函数包含子urls.py,进行url与子url的拼接。  
  • include函数调用理解:url拼接,传入的第二个参数为模块路径字符串 "app文件夹.urls"  
  • 所得的url是项目文件夹的中的url与子url拼接而来的,故注意不要多加斜杠。 -> 而一般在项目文件夹的url结尾加斜杠,比较规范。

记住传入模块路径时不用加.py后缀,python中文件路径字符串均无需加后缀。

3.URL向视图函数传参

  输入的url有时会包含特定信息,将此信息传递给视图函数,可用于处理特定的逻辑。①在url中使用变量: 在path的第一个参数(url字符串)中,使用 <参数名> 的方式可以传递参数,然后在视图函数中接收一个参数,视图函数中的参数必须与url中的参数名称保持一致;另外,url中可以传递多个参数。

②查询字符串: 在url中,不需要单独的匹配查询字符串的部分(通过'?'的形式进行传递,无需在url中进行体现,当使用该类url时,传入视图函数的request自动包含了该类信息),只需在视图函数中使用 request.GET.get('参数名称')/ request.GET['参数名称'] 的方式来获取。示例代码如下:

def author_id(request):
    author_id = request.Get['id']
    text = '作者的id是:%s'%author_id
    return HttpResponse(text)

  * 查询字符串使用的是get请求,故通过传入函数的request对象的 GET 方法来获取参数;并且由于 GET 返回的是一个类似字典的数据类型,故获取值的方式与字典的方式是一样的的。  

URL映射时指定默认参数

使用带有参数的url的时候也可不传入参数,只需在对应view函数的参数列表中指定参数默认值。

  • 使用的是python的特性,非Django特有

4.URL命名

对url进行命名,则可在代码中直接使用该别名(使用的时候用 reverse() 反转);这样在想修改url匹配时,无需多处修改,只需修改path()re_path()函数中的url即可;而在代码中可随时由url别名反转得到对应的url。    实现:   在path函数中,给关键字参数name传递参数以指定url名称。示例代码:

urlpatterns=[
       path(" ", views.index , name="index"),
       path("signin/", viwes.login , name="login"),
      ]

   

5.不同条件下URL的跳转

即输入一个url,跳转到的却是另一个url的页面;常用于在 登录/未登录 状态下返回不同的页面    实现:   使用shortcut模块的redirect()函数进行重定向,传入一个需跳转到的url(相对于主urls.py的url)。

   

6.应用命名空间

  对url起的别名是相对于整个项目的而言的,故须特别声明该url需处的应用进行区分(即为对应应用声明命名空间),否则在使用url别名进行反转时,不同应用中两个别名相同的url会发生混乱。(若不给url起别名,则不会发生该问题

指定方式: 在对应app文件夹下的urls.py中,设置全局变量app_name,其值为应用名称的字符串。则在使用 reverse( ) 函数对url别名进行反转时,传入字符串参数 app_name : url别名 替代原先的别名字符串,以指定app。

   

7.实例命名空间

实例:可以使用多个url拼接到同一个app,这样的url称为一个实例,一个app可创建多个实例。     对于映射到同一个app的多个url带来的问题:当使用 reverse() 函数进行反转时,若使用应用命名空间,则会在同一个应用的多个实例中引发混淆,故需使用在同一个app下不同实例的命名空间,在指定应用命名空间的时候用实例命名空间取代应用命名空间。

  • 即使用url别名进行反转得到指定app下的url时,同一个app下的各个实例仍无法区分。

    • 实例命名空间是在应用命名空间下申请不同的实例的各自命名空间。

    • 指定实例命名空间的时候必须已指定了应用命名空间。

      声明实例命名空间:   在 include()函数(进行实例url与主url拼接的时候)传入 namespace 关键字参数(最常用)。

        #### 8.include( )函数补充   include()函数用来①拼接实例url与对应主urls.py中url,详见url模块化,②且可以在拼接的时候指定实例命名空间;以下介绍用include()函数指定实例命名空间的三种方法:

Ⅰ.include(module,namespace=None):

  • module:app的urls.py模块的路径字符串
  • namespace:指定实例命名空间

Ⅱ. include((module,app_namespace),namespace=None):

  • include() 的第一个参数可以传入一个元组,其中第一个元素为app url.py模块的路径字符串,第二个元素为app的应用命名空间

    即应用命名空间可以在app的urls.py模块中通过app_name变量指定,也可以通过 include()函数指定。

Ⅲ. include(pattern_list):

  • pattern_list参数是一个列表。这个列表中装的是需要拼接的子url的path()re_path()函数。 可以将子url放在app的urls.py文件中,也可以放在include()函数的一个参数列表中。

   

9.reverse( )函数补充

  reverse()函数用来在代码中反转url别名,从而在代码中得到真正的url

reverse()一般用于在代码(view函数)中,得到真实的url,用于传入redirect()进行跳转;即一般与重定向函数搭配使用

  • 若在反转url的时候需要添加参数,则可以传递关键字参数kwargsreverse()函数  
  • 其中kwargs为一个字典,字典中的key对应真实url的参数名,而value对应需传递的值,用来向需要参数的url中传递参数。

  示例代码:

#views.py文件中:
detail_url=reverse('detail',kwargs={'artice_id':1,'page':2})

#urls.py文件中:
path('detail/<artice_id>/<page>',view函数,name="detail")

   

* 命名空间总结

  1. URL命名空间:  在使用path()函数时传入name参数指定,用以给path函数指定的url起名,则修改代码中的URL时,无需多处修改,只需修改path()函数中指定的URL模式即可;可用于在代码中通过reverse()函数高效地获得原url。  
  2. 应用命名空间:  在代码中使用url别名时,不同app下的别名相同的url会发生冲突,于是需要在不同app的urls.py模块中使用app_name指定应用命名空间,在代码中使用{{ 应用名:url别名 }} 即可精确指定url。  
  3. 实例命名空间:  由于同一个app可能有多个不同的实例(通过不同的url访问同一个app),若使用同一个应用命名空间,则会发生混淆,故在主模块的urls.py中使用include()函数拼接url的时候,传递namespace参数,为不同实例指定名字;至此,可以使用实例命名空间替代应用命名空间。  


Last Modified : 2020-03-09 17:50:26