• django框架学习:三十.反向解析url和命名空间


    前言

    反向解析url

    在实际的django项目中,经常需要获取某条url,未生成的内容配置url连接。

    例如:我在页面上展示一系列文章列表,每个条目都是超级链接,点击就进入该文章的详细页面,路由配置:path('post/<int:pk>/',views.some_view),

    在前端中需要为HTML标签<a>标签herf属性提供一个诸如http://www.xxx.com/post/3/的值。其中的域名部门django会自动帮你添加,我们需要关注的是怎么添加/post/3/。

    此时一定不能硬编码url为/post/3/,那样费事,不可伸缩,容易出错。试想如果哪天因为某些原因,需要将urlconf中的表达式改成entry/<int:pk>/,为了让链接正常工作,必需修改对应的herf属性值,于是你去项目里将所有的post/3/改为entry/3/吗?显然不合理。

    我们需要一种安全可靠,自适应的机制,当修改urlconf中的代码后,无需在项目源码中大范围的搜索,替换失效的硬编码url,为了解决这个问题,django中提供了一种解决方案,只需在url中提供一个name参数,并赋值你自定义的好记的,直观的字符串。通过这个name参数,可以反向解析url,反向url匹配,反向查询或者简单的url反查。

    在需要解析url的地方,对于不同层级,django提供了不同工具的用于url反查:

    >在模版语言中:使用url模板标签

    >在pyhon代码中:使用reverse()函数(0写视图函数等情况时)

    >在更高层的预处理django模型实例相关的代码中:使用 get_basolute_url()方法。(也就是在模型model中)

    实例:

    from django.urls import path

    from .import views

    2020年对应的归档url是/articles/2019/。

    对应的在模板代码中使用下面的模版方法获得他们:

     在python代码中,这样使用:

     其中起到核心作用的是我们通过name=“news-year-archive”为那条url起了一个可以被引用的名称。

    url名称name使用的字符串可以包含任何你喜欢的字符,但是过度放纵有可能重名带来的冲突,比如两个app取了相同的name,为了解决这个问题,又引出了下面的命名空间。

    url命名空间

    url命名空间可以保证反查到唯一的url,第三方应用始终使用命名空间是一个很好地做法,类似的他还允许你在一个应用有多个实例部署的情况下反查url,换句话讲,因为一个应用的多个实例共享相同的命名url,命名空间提供了一种区分这些命名url的方法。

    实现命名空间的做法很简单,在urlconf文件中添加app_name="polls"和namespace="author_polls"类似的定义。

    实例:

    以上面polls的应用的两个实例为例:"publisher-polls"和"author-polls"。

    假设我们已经在创建和显示投票时考虑了实例命名空间的问题,代码如下:

    urls.py

     app应用urls.py

     如果您当前的app实例是其中的一个,例如:我们正在渲染实例“author-polls”中的detail 视图,“polls:index”将解析到“author-polls”实例的index视图。

    根据以上设置可以使用一下查询:

    在基于类的方法中:

    reverse('polls':index,current_app=self.request.resolver_match.namespace)

    在模板中:

    {% url polls:index" %}

    如果没有当前的app实例,例如如果我们在站点其他地方渲染一个页面,"polls:index"将解析到polls注册的最后一个app实例空间,因为没有默认的实例,将使用注册polls的嘴周一个声明。

    url命名空间和include的urlconf

    可以通过两种方式指定ibclude和urlconf的应用名称空间

    第一种

    在include的urlconf模块中设置与urlpatterns属性相同级别的app_name属性。必须将实际模块或模块的字符串引用传递到include(),而不是urlpatterns本身的列表。

    polls/urls.py:

    from django.urls import path

    from . import views

    app_name = 'polls'

    urlpatterns = [

    path('', views.IndexView.as_view(), name='index'),

    path('<int:pk>/', views.DetailView.as_view(), name='detail'),

    ]

    urls.py:

    from django.urls import include, path

    urlpatterns = [

    path('polls/', include('polls.urls')),

    ]

    此时,polls.urls中定义的URL将具有应用名称空间polls。

    第二种

    include一个包含嵌套命名空间数据的对象,格式如下:

    (<list of path()/re_path() instances>, <application namespace>)

    下面是个例子:

    from django.urls import include, path

    from . import views

    polls_patterns = ([

    path('', views.IndexView.as_view(), name='index'),

    path('<int:pk>/', views.DetailView.as_view(), name='detail'), ], 'polls')

    urlpatterns = [

    path('polls/', include(polls_patterns)),

    ]

    这将include指定的URL模式到给定的app命名空间。

    可以使用include()的namespace参数指定app实例命名空间。如果未指定,则app实例命名空间默认为URLconf的app命名空间。

  • 相关阅读:
    ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
    reportlab设置字体
    Ansible 配置文件详解
    Ansible 配置文件详解
    如何在 FineUIMvc 中引用第三方 JavaScript 库
    如何在 FineUIMvc 中引用第三方 JavaScript 库
    如何在 FineUIMvc 中引用第三方 JavaScript 库
    如何在 FineUIMvc 中引用第三方 JavaScript 库
    div和span显示在同一行
    div和span显示在同一行
  • 原文地址:https://www.cnblogs.com/liushui0306/p/12870075.html
Copyright © 2020-2023  润新知