当前位置: 首页 > article >正文

Django框架视图与路由(一)

Django框架视图与路由(一)

文章目录

  • Django框架视图与路由(一)
    • @[toc]
    • 一、Django框架视图基础
    • 二、URL路由配置
      • 1.URL路由基础
      • 2.Django如何处理请求
      • 3.PATH路径转换器
      • 4.使用正则表达式
      • 5.URLconf在什么上查找
      • 6.指定视图参数的默认值
      • 7.包含其他的URLconf模块
      • 8.传递额外参数给视图函数
      • 9.反向解析
      • 10.命名空间

一、Django框架视图基础

我们可以把Django框架里的视图想象成餐厅里的服务员,帮助我们理解它的作用和工作方式。

视图就像服务员

在餐厅里,顾客(用户)进入餐厅(访问网站)后,会提出各种需求(发送请求),比如点菜(获取特定信息)。这时,服务员(视图)就会出现,接收顾客的需求(HttpRequest对象)。服务员会把顾客的需求传达给厨房(模型层和模板层),让厨房准备相应的菜品(处理数据)。最后,服务员把准备好的菜品(响应内容)端给顾客(返回HttpResponse对象)。

视图的工作流程

  1. 接收请求:当用户在浏览器中输入网址或者进行操作时,就相当于顾客向服务员提出需求。Django会创建一个包含请求信息的HttpRequest对象,就像服务员记录顾客的需求一样。
  2. 处理请求:视图接收到HttpRequest对象后,会根据请求的内容进行相应的处理。这可能包括查询数据库(从厨房获取食材)、调用其他函数(使用厨房的工具)等,以生成需要返回给用户的内容。
  3. 返回响应:处理完请求后,视图会返回一个HttpResponse对象,就像服务员把准备好的菜品端给顾客一样。这个对象包含了要显示给用户的内容,比如网页的HTML代码、图片等。

视图的分类

视图有两种类型,就像餐厅里有不同类型的服务员:

  • 基于函数的视图(FBV):就像普通的服务员,按照固定的流程为顾客服务。每次顾客提出需求,服务员都会按照相同的步骤处理。
  • 基于类的视图(CBV):就像专业的服务员,根据不同的情况提供不同的服务。比如,对于不同类型的顾客(不同的请求方法,如GET、POST),服务员会采用不同的服务方式。

示例说明

假设我们有一个简单的餐厅,顾客可以询问当前的时间。这时,服务员(视图)会看一下手表(获取当前时间),然后告诉顾客现在的时间(返回包含时间信息的响应)。以下是对应的代码示例:

from django.http import HttpResponse
import datetime
 
def current_datetime(request):
    # 获取当前时间
    now = datetime.datetime.now()
    # 生成包含时间信息的HTML代码
    html = "<html><body>It is now %s.</body></html>" % now
    # 返回响应
    return HttpResponse(html)

在这个示例中,current_datetime 函数就是一个视图,它接收顾客的请求(request 参数),获取当前时间,生成包含时间信息的HTML代码,并返回一个HttpResponse对象给顾客。


二、URL路由配置

1.URL路由基础

  • 对于高质量 Web 应用,简洁优雅的 URL 设计至关重要。Django 框架让设计人员可自由设计 URL 模式,不受框架约束。
  • URL 路由是 Web 服务入口。用户通过浏览器发送请求,会解析到指定 URL 地址,从而获得服务器响应,这是基本流程。
  • 在 Django 项目中,URL 路由配置通过 urls.py 文件完成。一个项目含多个 App 时会有多个 urls.py 文件,但不能放在同一目录。一般在项目根目录设根路由 urls.py,每个 App 下再定义各自的 urls.py,这是先进的解耦模式。
  • 总之,URL 路由是路径与视图函数的对应关系,起中间媒介作用,原理见图

在这里插入图片描述

Django的路由系统工作流程

客户端用户的http请求:图的左侧是客户端用户发出的http请求,这些请求通过箭头指向Django路由系统。

  • Django路由系统:位于图的右侧,是整个流程的核心部分。它接收来自客户端的http请求。
  • URL映射:在Django路由系统内部,包含了URL映射机制,图中列出了URL1、URL2、URL3等多个URL。这些URL将用户的http请求映射到相应的View处理函数。
  • View处理函数:每个URL对应一个View处理函数,这些函数在接收到请求后进行相应的处理,并最终返回一个HttpResponse对象,作为对客户端请求的响应。
from django.contrib import admin	# 调用模块导入对象,自带的管理员模块
from django.urls import path		# 调用django.urls导入path,这是一个负责URL路由配置的模块

urlpatterns = [
    path("admin/", admin.site.urls),	# 定义了一个数组,通过path定义具体的路径配置信息
    path('hello/', views.hello),
    ...
]

2.Django如何处理请求

  1. 请求接收:用户发起HTTP请求,由项目的wsgi.py接收,传递给URL解析器。
  2. URL路由:解析器加载urls.py,按顺序匹配urlpatterns中的条目,找到匹配的URL后,将请求派发给对应的视图函数或类视图。
  3. 中间件处理:请求在到达视图前,按settings.pyMIDDLEWARE顺序经过中间件,中间件可执行多种操作,如修改请求、处理异常等。
  4. 视图处理:视图接收HttpRequest对象,处理业务逻辑,查询数据库等,最终返回HttpResponse对象,可能会使用模板引擎渲染模板。
  5. 模板渲染:若视图使用模板,会加载并渲染模板,将数据插入模板标记,生成的内容作为响应的一部分。
  6. 响应处理:响应在返回用户前,再次经过中间件,中间件可对其检查、修改。
  7. 返回响应:处理后的HttpResponse对象经WSGI层返回给用户浏览器。
  8. 异常处理:视图或中间件抛出异常时,异常中间件捕获异常,开发时DEBUG=True可显示详细错误,生产环境则配置友好错误页面 。

3.PATH路径转换器

在Django中,PATH路径转换器是URL路由里用于匹配和捕获URL特定模式,并将匹配的路径段传递给视图函数的工具 。

内置PATH路径转换器

Django提供了多种内置的PATH路径转换器 :

  • str:匹配除斜杠/以外的任何非空字符串,若未专门指定转换器,此为默认使用的类型。例如path('v1/users/<str:username>', views.py)可匹配v1/users/zyyy
  • int:匹配0和正整数,返回int类型。如path('page/<int:page>', views.py)能匹配/page/100
  • slug:匹配字母、数字、下划线或连字符组成的字符串,可理解为url最后的注释、后缀等解释性字符 。例如path('detail/<slug:sl>', views.py)可匹配detail/this-is-django
  • uuid:匹配一个uuid格式的对象,需使用破折号且所有字母小写,例如075194d3 - 6885 - 417e - a8a8 - 6c931e272f00,返回一个UUID对象。
  • path:匹配任何非空字符串,包括路径分隔符/ 。比如path('v1/users/<path:ph>', views.py)可匹配/v1/goods/a/b/c

自定义PATH路径转换器

在某些复杂需求下,可自定义路径转换器 :

  1. 创建自定义路径转换器:例如创建一个匹配大写字母字符串的路径转换器,在blog/converters.py中编写如下代码:
class UppercaseConverter: 
    # 定义正则表达式,仅匹配大写字母
    regex = '[A-Z]+' 
    # 将路径段字符串转换为Python对象(可选,直接返回即可)
    def to_python(self, value): 
        return value  
    # 将Python对象转换为URL使用的字符串(可选,直接返回即可)
    def to_url(self, value): 
        return value
  1. 注册自定义路径转换器:在urls.py文件中导入并注册:
from django.urls import register_converter, path 
from blog.converters import UppercaseConverter  
# 注册自定义路径转换器
register_converter(UppercaseConverter, 'uppercase') 
# 定义一个视图函数作为示例
from django.http import HttpResponse  
def greet(request, name): 
    return HttpResponse(f"Hello, {name}!") 
# 使用自定义路径转换器
urlpatterns = [
    path('blog/greet/<uppercase:name>/', greet),
]

启动服务器后,http://127.0.0.1:8000/blog/greet/HELLO/可匹配成功,返回“Hello, HELLO!”;http://127.0.0.1:8000/blog/greet/hello/匹配失败,返回404页面 。

4.使用正则表达式

在Django中,使用正则表达式可实现复杂的URL模式匹配,主要通过re_path函数来完成,其提供了基于正则表达式的强大匹配能力,能处理更复杂的URL模式需求,通过自定义正则表达式匹配,可定义灵活且精确的路由规则 。

re_path基本语法

re_path的语法格式如下 :

from django.urls import re_path
urlpatterns = [
    re_path(r'^pattern$', view_function, name='route_name'),
]

其中:

  • r’^pattern$’ 是正则表达式,用于匹配URL 。^表示匹配字符串的开始位置,$表示匹配字符串的结束位置,确保整个URL与正则表达式完全匹配 。
  • view_function 是对应的视图函数,当URL匹配成功时,Django会调用该视图函数处理请求 。
  • name 是路由的名称(可选),可用于反向解析URL 。

示例

  • 匹配用户名的路由:假设要求用户名只能包含字母、数字或下划线,长度为3到15个字符。示例代码如下 :
# urls.py
from django.urls import re_path
from django.http import HttpResponse
 
# 示例视图函数
def user_profile(request, username):
    return HttpResponse(f"User profile: {username}")
 
# 使用re_path定义路由
urlpatterns = [
    re_path(r'^profile/(?P<username>[a-zA-Z0-9_]{3,15})/$', user_profile),
]

测试时,访问http://127.0.0.1:8000/profile/john_doe/,会返回User profile: john_doe;访问http://127.0.0.1:8000/profile/john - doe/,匹配失败,返回404页面 。这里(?P<username>[a-zA-Z0-9_]{3,15})是一个命名分组,?P<username>指定组名为username[a-zA-Z0-9_]{3,15}表示匹配由字母、数字、下划线组成,长度在3到15个字符之间的字符串,并将匹配到的内容作为关键字参数传递给user_profile视图函数 。

  • 匹配日期格式:假设要匹配URL中的日期格式,并将其解析为视图函数的参数。示例代码如下 :
# urls.py
from django.urls import re_path
from django.http import HttpResponse
from datetime import datetime
 
# 示例视图函数
def event_view(request, year, month, day):
    date = f"{year}-{month}-{day}"
    return HttpResponse(f"Event date: {date}")
 
# 使用re_path定义路由
urlpatterns = [
    re_path(r'^event/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', event_view),
]

测试时,访问http://127.0.0.1:8000/event/2024/11/17/,返回Event date: 2024 - 11 - 17;访问http://127.0.0.1:8000/event/24/11/17/,匹配失败。这里(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})分别匹配4位数字的年份、2位数字的月份和2位数字的日期,并作为关键字参数传递给event_view视图函数 。

  • 结合正则表达式实现高级功能
    • 匹配十六进制颜色代码:十六进制颜色代码格式为#RRGGBB#RGB,示例代码如下 :
# urls.py
from django.urls import re_path
from django.http import HttpResponse
 
# 示例视图函数
def color_view(request, color):
    return HttpResponse(f"Color: #{color}")
 
# 使用re_path定义路由
urlpatterns = [
    re_path(r'^color/(?P<color>[A - Fa - f0 - 9]{6}|[A - Fa - f0 - 9]{3})/$', color_view),
]

测试时,访问http://127.0.0.1:8000/color/FF5733/,返回Color: #FF5733;访问http://127.0.0.1:8000/color/123/,返回Color: #123;访问http://127.0.0.1:8000/color/GG5733/,匹配失败 。
匹配自定义Slug格式:假设自定义Slug格式由字母、数字、连字符组成,示例代码如下 :

# urls.py
from django.urls import re_path
from django.http import HttpResponse
 
# 示例视图函数
def article_view(request, slug):
    return HttpResponse(f"Article: {slug}")
 
# 使用re_path定义路由
urlpatterns = [
    re_path(r'^article/(?P<slug>[a-zA-Z0-9 -]+)/$', article_view),
]

测试时,访问http://127.0.0.1:8000/article/django - tutorial/,返回Article: django - tutorial;访问http://127.0.0.1:8000/article/django_tutorial/,匹配失败 。

与基于path的路径转换器相比,re_path提供了更高的灵活性,适用于复杂的URL模式需求 。

5.URLconf在什么上查找

URLconf在请求的URL上查找,将其当作一个普通的Python字符串,查找时不包括GET和POST参数以及域名 。例如,对于请求地址http://www.example.com/myapp/ ,URLconf查找的是myapp/;对于请求地址http://www.example.com/myapp/?page=3 ,URLconf查找的同样是myapp/

通常情况下,Django确定要使用的根URLconf模块,一般是settingsROOT_URLCONF设置的值 。但如果传入的HttpRequest对象具有urlconf属性(由中间件设置),则其值将用于代替ROOT_URLCONF设置 。接着,Django加载该Python模块并查找变量urlpatterns,它是django.conf.urls.url() 实例(在Django 2.x+版本中通常是django.urls.path()django.urls.re_path() 实例)的一个Python列表 。Django按顺序遍历每个URL模式,并在与请求的URL匹配的第一个模式停下来 。

6.指定视图参数的默认值

在Django中指定视图参数默认值是一个方便的技巧,当URL没有为视图函数的参数提供值时,将使用默认值。以下通过示例说明:

  • 示例一:假设在urls.py中有如下配置:
from django.conf.urls import url
from. import views
urlpatterns = (
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>(0-9)+)/$', views.page),
)

在视图函数(如blog/views.py)中定义:

def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    #...
    pass

这里两个URL表达式都指向views.page视图 。第一个表达式没有传递任何参数,若匹配到第一个样式,page()函数将会对参数num使用默认值"1";如果第二个表达式匹配成功,page()函数将使用正则表达式传递过来的num的值 。注意设置默认参数值为字符串"1",因为捕捉给num的值总是字符串 。

  • 示例二:如果在urls.py中有:
from django.urls import path
from. import views
urlpatterns = [
    path('blog/', views.page),
    path('blog/page<int:num>/', views.page),
]

视图函数为:

def page(request, num = 1):
    pass

此时第一个模式不会从URL中捕获任何值,如果第一个模式匹配,page()函数将使用num参数的默认值1;如果第二个模式匹配,page()将使用捕获的num值 。

  • 示例三:构建Django项目时,在urls.py 中的路径为path('device_id/<str:device_id>/readings/<int:num_readings>, views.results, name='results'),若想在用户未输入读数时避免404,可在视图中指定默认读数 。视图函数定义为def results(request, device_id="", readings=10):,同时使用re_path以便用正则表达式声明num_readings是可选的 ,如urlpatterns = ( re_path( 'device_id/(?P<device_id>\w+)/readings/(?P<num_readings>\d+)?',views.results,name='results' ),)

综上,通过在视图函数中直接为参数指定默认值,结合URL的匹配规则,可实现视图参数默认值的设定 。

7.包含其他的URLconf模块

在Django中,将每个应用程序设置一个URLConf模块,并将其包含在根URLConf模块中,是一种良好的开发实践 。这样做有助于实现代码的模块化和可维护性,特别是在大型项目中。具体步骤和要点如下:

在根URLConf模块中包含应用的URLConf模块:在根urls.py文件中,使用include函数来包含其他应用的URLConf模块。例如:

from django.contrib import admin
from django.urls import path, include
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('books.urls')),
]

上述代码中,path('', include('books.urls')) 表示Django会在books/urls.py文件中搜索URL模式 。

应用的URLConf模块配置:以books/urls.py为例,它可以定义该应用特有的URL模式,示例代码如下:

from django.urls import path
from. import views
 
urlpatterns = [
    path('books/<int:pk>/', views.book_detail),
    path('books/<str:genre>/', views.books_by_genre),
    path('books/', views.book_index),
]

当请求的URL与这些模式匹配时,会调用相应的视图函数。比如,/books/crime/的URL请求将与path('books/<str:genre>/', views.books_by_genre)匹配,Django会调用函数views.books_by_genre(request, genre = “crime”)/books/25/的URL请求将匹配path('books/<int:pk>/', views.book_detail),Django将调用函数views.book_detail(request, pk =25)

注意事项
根URLConf模块设置:通常在settings.py文件中通过ROOT_URLCONF指定根级url的配置,默认情况下,它被设置为项目的urls.py。根urls.py中针对应用配置的URL名称,是该应用所有URL的总路径 。
正则表达式相关:在编写URL模式时,若使用正则表达式,要注意一些规则。例如,若要从url中捕获一个值,需要在它周围设置一对圆括号;不需要添加前导反斜杠;每个正则表达式前面的r表示字符串不转义;urlpatterns中的每个正则表达式在第一次访问时被编译,可提高系统速度。另外,指向include()的正则表达式通常不包含$(字符串结尾匹配符),但会包含一个斜杆。每当Django遇到include()时,它将截断匹配的URL,并把剩余的字符串发往被包含的URLconf作进一步处理 。
参数传递:被包含的URLconf会接收来自父URLconfs的被捕获的参数,并传递给其中的视图函数 。例如在root urls.py 中有(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),在foo/urls/blog.py中的视图函数就能接收到username这个参数 。

8.传递额外参数给视图函数

在Django中传递额外参数给视图函数,常见方式如下:

使用path()函数捕获URL参数:可以在path()函数的路由中使用尖括号捕获URL中的部分作为参数传递给视图函数。例如:

# urls.py
from django.urls import path
from.views import my_view
urlpatterns = [
    path('example/<str:extra_param>/', my_view, name='my_view'),
]
# views.py
from django.http import HttpResponse
def my_view(request, extra_param):
    return HttpResponse(f'This is my view with extra_param: {extra_param}')

当访问/example/some_value/时,some_value会作为extra_param的值传递给my_view函数 。
传递多个参数:在URL中使用多个捕获组来传递多个参数。例如:

# urls.py
from django.urls import path
from.views import my_view
urlpatterns = [
    path('example/<str:extra_param>/<int:number_param>/', my_view, name='my_view'),
]
# views.py
from django.http import HttpResponse
def my_view(request, extra_param, number_param):
    return HttpResponse(f'This is my view with extra_param: {extra_param} and number_param: {number_param}')

访问/example/some_value/42/时,some_value作为extra_param的值,42作为number_param的值传递给my_view函数 。
提供默认参数:为避免客户端请求因缺少参数导致404错误,可在URL配置中为参数提供默认值。例如:

# urls.py
from django.urls import path
from.views import my_view
urlpatterns = [
    path('example/<str:extra_param>/<int:number_param>/', my_view, name='my_view'),
    path('example/', my_view, {'extra_param': 'default_value', 'number_param': 0}, name='my_view_default'),
]
# views.py
from django.http import HttpResponse
def my_view(request, extra_param='default_value', number_param=0):
    return HttpResponse(f'This is my view with extra_param: {extra_param} and number_param: {number_param}')

此时访问http://mysite.com/example/,视图函数将使用默认值 。
使用字典传递额外参数:在path()函数中包含Python字典类型的参数,再传递给视图函数 。例如:

# urls.py
from django.urls import path
from.views import my_view
urlpatterns = [
    path('example/', my_view, {'key': 'value'}, name='my_view'),
]
# views.py
from django.http import HttpResponse
def my_view(request, key):
    return HttpResponse(f'This is my view with key: {key}')

通过GET请求传递参数:在URL中通过?参数名字=value&参数名字=value的形式传递多个参数,后端通过request.GET.get('参数名字')获取传递的参数。例如:

# views.py
def div_page(request):
    page_num = request.GET.get('page')
    content = request.GET.get('content')
    print(content)
    print(page_num)
    return HttpResponse(int(page_num))

URL为http://127.0.0.1:8000/page/?page=5&content=3 。这种方式后端无需在函数中定义额外参数,较为灵活 。
使用正则表达式传递参数
- 无名分组:通过未命名的正则表达式组捕获参数,按顺序作为位置参数传递给视图函数。例如:

# urls.py
from django.urls import re_path
from.views import my_view
urlpatterns = [
    re_path(r'^example/(\d+)/(\w+)/', my_view),
]
# views.py
from django.http import HttpResponse
def my_view(request, param1, param2):
    return HttpResponse(f'param1: {param1}, param2: {param2}')
- **有名分组**:使用命名的正则表达式组`(?P<name>pattern)`捕获参数,按关键字参数传递给视图函数。例如:
# urls.py
from django.urls import re_path
from.views import my_view
urlpatterns = [
    re_path(r'^example/(?P<param1>\d+)/(?P<param2>\w+)/', my_view),
]
# views.py
from django.http import HttpResponse
def my_view(request, param1, param2):
    return HttpResponse(f'param1: {param1}, param2: {param2}')

需要注意,当混杂命名正则和未命名正则两种样式时,未命名的组会被忽略,只有命名的组才会传递给视图函数 。

9.反向解析

在Django中,反向解析指通过一些方法得到一个结果,该结果可以访问到对应的url并触发视图函数运行 。

反向解析的用途

在软件开发初期,url地址路径设计可能不完善,后期若需调整,若项目中多处使用该路径,直接修改路径会很繁琐。通过反向解析,在编写 url(regex, view, kwargs=None, name=None) 时,利用参数 name 为url路径起别名,项目中通过别名获取路径。日后路径变化,只要别名与路径对应关系不变,就无需修改使用该路径的各处代码 。

反向解析的实现方式

  1. 模板中超链接的解析:在模板中使用 {% url '别名' %} 的方式进行反向解析。例如在 index.html 中,<a href="{% url 'test_app:test2' %}">反向解析fan2</a> ,这里 test_app 是命名空间,test2 是路由别名。如果路由配置了命名空间,格式通常为 命名空间:别名
  2. 视图函数中的重定向:在视图函数中,从 django.urls 引入 reverse 函数,使用 redirect(reverse('别名')) 进行反向解析重定向。如 def redirect_view(request): return redirect('test_app:test2') 。若路由存在参数,传递方式为 redirect(reverse('别名', args=(参数值,))) (位置参数)或 redirect(reverse('别名', kwargs={'参数名':参数值})) (关键字参数) 。
  3. 带参数的反向解析:当路由存在分组(无名分组和有名分组)时,反向解析需传递相应参数。例如对于无名分组 url(r'^aritcle/(\d+)/$',views.article,name='article_page') ,反向解析时后端可使用 reverse('article_page', args=(1,)) ;对于有名分组 url(r'^user/(?P<uid>\d+)/$',views.article,name='user_page') ,后端反向解析写法可以是 reverse('user_page', kwargs={'uid': 1}) 。前端写法类似,如 <a href="{% url 'user_page' uid=1 %}">链接</a>

反向解析的相关函数

  • reverse:通过路由命名空间或可调用视图对象生成路由地址。有 viewname(路由命名或可调用视图对象)、urlconf(设置反向解析的URLconf模块,默认使用主路由)、args(以列表方式传递路由地址变量)、kwargs(以字典方式传递路由地址变量)、current_app(提示当前正在执行的视图所在的项目应用)等参数 。
  • resolve:通过路由地址获取路由对象信息,有 path(代表路由地址)、urlconf(设置反向解析的URLconf模块,默认使用主路由)两个参数,返回的路由对象有 func(视图函数或视图类对象)、args(以列表格式获取路由变量信息)、kwargs(以字典格式获取路由变量信息)、url_name(获取路由命名name)等内置函数方法来获取具体路由信息 。

10.命名空间

在Django中,命名空间(Namespace)是表示标识符可见范围的概念,它能有效避免因不同应用中定义相同 name 而导致的URL反解错误 。

由于 name 没有作用域,Django反解URL时会在项目全局顺序搜索,一旦找到第一个 name 指定的URL就立即返回。所以在开发项目时,若不同应用的 urls 中不小心定义了相同的 name,可能致使URL反解出错。为解决此问题,引入了命名空间 。

在Django中,include 函数可用于设置命名空间,其形式如 include(module(, namespace=None, app_name=None ))include(pattern_list)include((pattern_list, app_namespace, instance_namespace)) ,其中 app_namespace 即应用命名空间,instance_namespace 即实例命名空间 。带有命名空间的URL组成方式为 “命名空间:名称”,以 : 为分隔符,且命名空间URL支持嵌套,例如 “foo:bar:whiz” 。

解析命名空间URL时,假设要解析 “myapp:index” 这样的命名空间URL :

  1. django会查找符合条件(此例中为 myapp)的应用命名空间,返回一个符合条件的实例命名空间列表 。
  2. 若有当前应用实例被定义,即用于渲染的模版中的 Context 或者 RequestContext 中的 current_app 属性被设置,那么该值就是当前应用实例,使用该实例 。
  3. 若没有当前应用实例被定义,会查找一个默认应用实例,该实例命名空间的名字与应用命名空间的名称一样。
  4. 若没有默认应用实例,则会按照声明次序,返回最后一个被声明的实例命名空间 。
  5. 若第一步没有匹配条件的应用命名空间,django会直接去查找匹配的实例命名空间 。

例如在项目的 urls.py 中,可通过如下方式设置命名空间:

from django.urls import path
from myapp import views
from django.conf.urls.static import static
from django.conf import settings
from django.conf.urls import re_path,include
from myapp import *
from myapp02 import *
 
urlpatterns = [
    # path('admin/', admin.site.urls),
    path('hello/',views.hello),
    path('login/',views.login,name = 'Log'),
    re_path(r"^myapp/",include(("myapp.urls","myapp"))), #这里使用元组设置命名空间为myapp
    re_path(r"^myapp02/",include(("myapp02.urls","myapp02"))), 
] + static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

在应用的 urls.py 中,例如 app1 urls.py

# !/usr/bin/env python  
#  -*- coding:utf-8 -*- 
from django.conf.urls import url
from myapp import views
from django.urls import re_path
 
urlpatterns = [
    re_path(r'^index/',views.index,name='index'),
    url(r'^hello/([0-9]{4})/$', views.year_archive,name='y'),
    url(r'^hello/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^hello/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

在视图函数中,如 app1 views.py ,可通过命名空间反向解析URL :

from django.shortcuts import render
from django.http import HttpResponse
from django.urls import reverse
 
#  Create your views here. 
#  request 是固定写法
def index(request):
    return HttpResponse(reverse("myapp:index"))

在模板中使用 {% url %} 标签访问时,若存在多级命名空间,如在 portfolio_menu.urlsstore.urlsproduct.urls 分别设置了命名空间 portfoliostoreproduct ,且 product.urls 中有视图的 namelist ,理论上可通过类似 {% url portfolio:store:product:list %} 的方式访问,但需注意配置正确,避免出现如 django.core.exceptions.ImproperlyConfigured 等错误 。


http://www.kler.cn/a/598666.html

相关文章:

  • Ruby语言的控制结构
  • 计算机二级web易错点(6)-选择题
  • 图像处理篇:图像预处理——从数据到模型的桥梁
  • Linux__之__基于UDP的Socket编程网络通信
  • 智慧座椅无线手机充电器:开启便捷充电新时代
  • SQLServer列转行操作及union all用法
  • 雪花算法生成分布式唯一ID
  • 从零构建大语言模型全栈开发指南:第一部分:数学与理论基础-1.2.3层归一化(LayerNorm)与残差连接的原理与代码实现
  • 用selenium+ChromeDriver豆瓣电影 肖申克的救赎 短评爬取(pycharm 爬虫)
  • 通过Typora + PicGo + 阿里云对象存储(OSS)实现图床
  • JAVA中数组(Array)‌ 和 ‌链表(LinkedList)‌ 是两种基础的数据结构
  • 详解如何通过Python的BeautifulSoup爬虫+NLP标签提取+Dijkstra规划路径和KMeans聚类分析帮助用户规划旅行路线
  • 进程状态与PV操作
  • Java安全-类的动态加载
  • 本地部署Dify 添加Ollama模型DeepSeek
  • matlab的meshgrid
  • Mysql架构理论部分
  • QT二 QT使用generate form 生成常用UI,各种UI控件
  • 关于Docker是否被淘汰虚拟机实现连接虚拟专用网络Ubuntu 22.04 LTS部署Harbor仓库全流程
  • STM32滴答定时器(SysTick)原理及延时函数实现