Django学习
Django学习
文章共计26个章节
文章目录
第一章 Django介绍和相关术语
一、Django介绍
1.简介
Django是Python语言中的一个web框架,Python语言中主流的web框架有Django、Tornado、Flask等多种。Django相较与其他web框架,其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等功能,是一个全能型框架,拥有自己的Admin数据管理后台,第三方工具齐全,性能折中。缺点:功能太多,数据分表复杂,高性能扩展复杂。
2.安装
1.pip安装:在cmd命令窗口中,输入:
pip install django
2.pycharm安装:在file>>settings>>project>>project interpreter 中搜索django,进行安装。
3.下载安装包安装:在官网https://www.djangoproject.com/download/ , 下载 django-master.tar,解压后,在解压目录中 运行 cmd(或者在cmd中切换到解压目录),然后通过输入命令:
python setup.py install
3.文档
官方文档的链接在:https://docs.djangoproject.com/en/2.2/,
点击页面右下角的language按钮,可以选择zh-hans,显示中文,只有部分页面有中文翻译,点击页面右下角的Documentation version,可以选择版本。
二、Django相关知识学习
1.Django结构
2.相关术语和规范
1.B/S 和C/S
Django是用于开发B/S架构的软件的,软件主要分为B/S架构和C/S架构:
B/S:全称Browser/Server(浏览器/服务器)
C/S:全称Client/Server(客户端/服务器)
2.MVC
MVC全名是Model View Controller,是模型(Model)—视图(View)—控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
- M:管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为,(或者叫做“业务规则”)
- V:负责把数据格式化后呈现给用户
- C:接受外部用户的操作,根据操作访问模型获取数据,并调用视图显示这些数据,控制器是将模型和视图隔离,并成为二者之间的联系纽带。
3.MTV
Django也是一个MVC框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式:
-
M: 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。
-
T: 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
-
V: 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。
4.ORM
对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的–“虚拟对象数据库”。
ORM方法论基于三个核心原则:
-
简单:以最基本的形式建模数据。
-
传达性:数据库结构被任何人都能理解的语言文档化。
-
精确性:基于数据模型创建正确标准化的结构。
ORM是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于SQL 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法。ORM技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化。
第二章 项目搭建
一、Django构建项目
1、cmd命令行构建项目
-
cmd窗口中,切换到指定的项目文件夹,执行:
django-admin startproject mysite
其中 mysite 是你的项目名称
这时会在指定的项目文件夹中,生成一个 mysite 文件夹,目录结构如下:
mysite/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py
这些目录和文件的说明如下:
- 最外层的mysite/ 根目录是项目的名称
- manage.py 是管理 Django 项目的命令行工具
- 里面一层的 mysite/ 目录包含你的项目主应用,它是一个 Python 包
- mysite/_init_.py:一个空文件,告诉 Python 这个目录是一个 Python 包
- mysite/settings.py:项目的配置文件
- mysite/urls.py:项目的 url路由配置
- mysite/wsgi.py:用于你的项目的与WSGI兼容的Web服务器入口,用于项目部署
-
cmd窗口中,进入最外层的mysite
-
在这个目录下,我们可以输入如下命令,创建一个新的子应用:
django-admin startapp first_app
-
在该cmd目录下执行如下命令,可以启动项目:
python manage.py runserver
该命令后续可以增加参数,如:
python manage.py runserver 8081 python manage.py runserver 127.0.0.1:8082
cmd窗口中会出现如下信息:
F:\django_study\first_pro>python manage.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. July 03, 2019 - 16:11:57 Django version 2.2.1, using settings 'first_pro.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. [03/Jul/2019 16:13:06] "GET / HTTP/1.1" 200 16348 [03/Jul/2019 16:13:06] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423 [03/Jul/2019 16:13:06] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876 [03/Jul/2019 16:13:06] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692 [03/Jul/2019 16:13:06] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184 Not Found: /favicon.ico [03/Jul/2019 16:13:06] "GET /favicon.ico HTTP/1.1" 404 1975
-
在浏览器中访问第4步提示的服务器网址:Starting development server at http://127.0.0.1:8000/ 中的 http://127.0.0.1:8000/ ,会出现如下欢迎页面:
-
第5步能够打开一个 django 的欢迎页面,是因为第 4 步 中的命令,启动了django自带的一个简易web服务器,它是一个用纯 Python 写的轻量级的 Web 服务器。仅仅用于开发环境,不要在生产环境使用。
在这个服务器中,在需要的情况下会对每一次的访问请求重新载入一遍 Python 代码。所以你不需要为了让修改的代码生效而频繁的重新启动服务器。然而,一些动作,比如添加新文件,将不会触发自动重新加载,这时你得自己手动重启服务器。
2、pycharm构建项目
- pycharm 中 file >> new project >> django
PS:只有 pycharm professional版本才可以直接创建django项目
- location 中,前面路径,选择你自己的项目路径, untitled 项目名改为 firstdjangopycharm 变成如下:
F:\py_study\firstdjangopycharm
-
project interpreter 点击 左边的 三角形 ,选择一个合适的 解释器
-
more settings, 点击 左边的 三角形,设置 applications name,点击 create
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BJZpX1wt-1655909267141)(.\imgs\pycharm_first_app.png)]
-
查看目录结构如下:
其中polls子应用下各文件的说明如下:
- migrations : 执行数据库的迁移操作,就是把 models 中的 model 映射到数据库
- admin :admin管理界面文件
- apps: 本应用的相关配置文件
- models:数据库的model文件
- tests:测试函数文件
- views:视图文件
-
启动项目
1.运行根目录下的manage.py, 第一次会运行失败,因为没有添加参数
2.在pycharm的右上角
选择 edit configurations
3.在 parameters 中写入 runserver 0.0.0.0:8000
4.再次运行 manage.py,控制台显示信息如下:
5. 在浏览器中访问: http://127.0.0.1:8000 , 可以看到django的欢迎页面
-
添加第一个页面
-
修改polls/views.py,增加如下代码:
from django.http import HttpResponse def index(request): return HttpResponse("欢迎学习Django!")
这是 Django 中最简单的视图。
定义了一个index()函数,第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含get或post的内容,用户浏览器,系统等信息在里面(后面会详细讲,先了解一下就可以)。
-
在polls目录下新建 urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
-
修改 主应用下的urls.py(firstdjangopycharm/urls.py)
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('polls/', include('polls.urls')), path('admin/', admin.site.urls), ]
-
重新启动manage.py
-
浏览器中访问:http://127.0.0.1:8000/polls/,浏览器会显示我们在 views 中返回的内容:
欢迎学习Django!
-
第三章 Django配置
一、django配置
1、整体介绍
django项目创建后,在主应用中,会有一个settings.py文件,这个就是该项目的配置文件
- settings文件包含Django安装的所有配置
- settings文件是一个包含模块级变量的python模块,所以该模块本身必须符合python规则,并且可以使用python的语法
- settings中的所有配置项的key必须全部大写
- settings中每一个配置项都有默认值,默认配置内容在django/conf/global_settings.py中可以查看到,项目中不需要导入该模块,django框架会自动获取
- settings中可以添加自定义的配置项
2、应用settings文件
-
manage.py启动
默认在manage.py中配置:
if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "firstdjangopycharm.settings")
-
手动指定配置文件位置
cmd命令启动如下:
python manage.py runserver 0.0.0.0:8000 --settings=firstdjangopycharm.settings
-
服务器部署启动
在wsgi.py中配置:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "firstdjangopycharm.settings")
3、常用配置项
import os
"""
当前文件所在文件夹的上一级目录的绝对路径
切记2个 os.path.dirname
"""
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
"""
用于加密session,一个随机的字符串
这样生成:
from django.core.management import utils
utils.get_random_secret_key()
"""
SECRET_KEY = '=*f&bx760nyar7@8lb8!w$9h(3ea6p3apl$iua!td1q%-u5r4='
# 调试模式,可以看到错误的所有相信信息,部署时一定要修改为False
DEBUG = True
"""
允许访问的域名设置
开发环境不用理会
运行环境,配置 DEBUG = False后,
如果允许所有域名访问,则设置 ALLOW_HOSTS = ['*']
如果指定某些域名可以访问,则设置 ALLOW_HOSTS = ['*.baidu.com']
"""
ALLOWED_HOSTS = []
"""
应用的配置,
如:'polls.apps.PollsConfig'
如果没有 PollsConfig ,那么可以配置为 'polls'
"""
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles', # 只有 DEBUG = Ture 才有效
'polls' # 子应用必须配置,否则不起作用
]
"""
中间层配置
自己编写的 中间层 需要配置在最后
譬如:
mymidlle.md.TestMiddleware
"""
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', # 自动给网址最后加/
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 配置基础的urls
ROOT_URLCONF = 'firstdjangopycharm.urls'
# 配置模板
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# 服务器部署的WSGI配置
WSGI_APPLICATION = 'firstdjangopycharm.wsgi.application'
"""
数据库配置
mysql在python3的使用,需要在 __init__.py 中加入以下代码:
import pymysql
pymysql.install_as_MySQLdb()
"""
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_test1',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
"""
root用户密码验证
"""
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# 语言选择 , zh-Hans 为中文
LANGUAGE_CODE = 'en-us'
# 时区 Asia/Shanghai 是中国时区
TIME_ZONE = 'UTC'
# 国际化
USE_I18N = True
# 本地化
USE_L10N = True
# 使用时区,配套TIME_ZONE使用,必须设置为 False
USE_TZ = False
"""
静态文件的路径,默认是 static
如果在各自项目的static目录以外,还有目录存放静态文件,需要添加如下属性:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "common_static1"),
'/var/www/static/',
)
"""
STATIC_URL = '/static/'
4、程序中获取settings中的配置项
如果在项目代码中需要获取settings中的配置项,这样获取:
# 切记不要导入具体的settings模块的路径,会形成高耦合
# 这样的方式是不可取的:from mysite import settings
from django.conf import settings
d = settings.DEBUG
第四章 URLConf调度器
一、URL调度器
1、工作原理
django通过urlconf来映射视图函数,只区分路径,不区分http方法
- Django确定要使用的根URLconf模块,一般是在settings中的ROOT_URLCONF设置的值,但是如果传入 HttpRequest 对象具有一个urlconf 属性(由中间件设置),则其值将用于代替 ROOT_URLCONF设置。
- Django加载该URLconf模块并查找变量 urlpatterns,它是一个列表django.urls.path() 和 / 或django.urls.re_path()实例。
- Django按顺序遍历每个URL模式,并停在与请求的URL匹配的第一个URL模式,需要特别注意编写的顺序
- 一旦某个URL模式匹配,Django就会导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的视图方法)。该视图通过以下参数传递:
- 一个HttpRequest实例。
- 如果匹配的URL模式没有返回任何命名组,则来自正则表达式的匹配作为位置参数提供。
- 关键字参数由路径表达式匹配的任何命名部分组成,并由可选的kwargs参数传给 django.urls.path()或django.urls.re_path()。
- 如果没有URL模式匹配,或者在此过程中的任何点发生异常,Django将调用适当的错误处理视图
2、简单示例
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),
]
笔记:
-
从URL中捕获值,请使用尖括号
-
捕获的值可以选择包含转换器类型。例如,用于 <int:name>捕获,前面的int指整数参数,name是参数的名称
-
没有必要添加一个前导斜杠,因为每个URL都有,例如,使用articles而不是/articles。
-
示例请求说明:
- /articles/2005/03/ 匹配列表中的第三个条目。Django会调用这个函数,views.month_archive(request, year=2005, month=3)
- /articles/2003/ 会匹配列表中的第一个模式,而不是第二个模式,因为模式是按顺序测试的,而第一个模式是第一个要传递的测试。看看利用匹配顺序插入像这样的特殊情况。在这里,Django会调用这个函数 views.special_case_2003(request)
- /articles/2003 不匹配任何这些模式,因为每种模式都要求URL以斜线结尾,不过在浏览器访问时,会自动添加 / 。
- **/articles/2003/03/building-a-django-site/ **将匹配最终模式。Django会调用这个函数 。views.article_detail(request, year=2003, month=3, slug=“building-a-django-site”)
3、路径转换器
- str:匹配任何非空字符串,不包括路径分隔符’/'。如果转换器不包含在表达式中,这是默认值。
- int:匹配零或任何正整数。返回一个int。
- slug:匹配由ASCII字母或数字组成的字符串,以及横线和下划线字符。例如, building-your-1st-django_site。
- uuid:匹配格式化的UUID。为防止多个URL映射到同一页面,必须包含破折号,并且字母必须是小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID实例。
- path:匹配任何非空字符串,包括路径分隔符 ‘/’,可以匹配完整的URL路径,而不仅仅是URL路径的一部分str,使用时要谨慎,因为可能造成后续的所有url匹配都失效。
4、自定义路径转换器
转换器是一个包含以下内容的类:
- 一个regex类属性,作为一个re匹配字符串。
- to_python(self, value)方法,它处理匹配的字符串转换成要传递到视图函数的类型。
- to_url(self, value)方法,用于处理将Python类型转换为URL中使用的字符串。
定义方式如下:
-
新建一个converters.py文件,在文件中定义一个FourDigitYearConverter类:
class FourDigitYearConverter(object): regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value
-
使用register_converter()方法在URLconf中注册自定义转换器类 :
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) ]
5、使用正则表达式
使用正则表达式匹配路径,请使用 re_path()而不是path()
在Python正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,并且 pattern是一些要匹配的模式
示例:
from django.urls import path, re_path
from . import views
# url() 是 re_path 的别名,不推荐使用
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
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),
]
注意事项:
- 匹配的URL会受到一些限制。例如,年份10000将不再匹配,因为年份整数限制为四位数字
- 无论正则表达式匹配什么类型,每个捕获的参数都以字符串的形式发送到视图
- 除了命名的组语法,例如(?P<year>[0-9]{4}),也可以使用较短的未命名组,例如([0-9]{4}),但是不建议这样使用,会引起未知的匹配
嵌套参数:
from django.urls import re_path
urlpatterns = [
# 不推荐, 匹配 blog/page-3/
re_path(r'^blog/(page-(\d+)/)?$', blog_articles),
# 推荐 ,匹配:comments/page-2/ 路径到 comments(request, page_numer)
re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', comments),
]
6、使用默认值
URLConf中:
from django.urls import path
from . import views
urlpatterns = [
# http://127.0.0.1:8000/polls/blog/ 等同于 http://127.0.0.1:8000/polls/blog/1/
path('blog/', views.page),
# http://127.0.0.1:8000/polls/blog/1/
# http://127.0.0.1:8000/polls/blog/10/
# http://127.0.0.1:8000/polls/blog/99/
path('blog/<int:num>/', views.page),
]
views中:
def page(request, num=1):
# 编写对应的业务逻辑
7、错误处理
- handler400- 状态码400
- handler403- 状态码403
- handler404- 状态码404
- handler500- 状态码500
-
在 settings中修改配置:
DEBUG = False ALLOWED_HOSTS = ['*', ]
-
在主应用的urls中配置:
# polls是子应用 handler404 = "polls.views.page_not_found"
-
在polls应用的views中添加函数page_not_found:
def page_not_found(request, exception): return HttpResponse('自定义的404错误页面')
8、引用其他URL调度器
-
多个 patterns
from django.urls import include, path extra_patterns = [ path('reports/', credit_views.report), path('reports/<int:id>/', credit_views.report), path('charge/', credit_views.charge), ] urlpatterns = [ path('', main_views.homepage), path('help/', include('apps.help.urls')), path('credit/', include(extra_patterns)), ]
-
使用include消除重复前缀
from django.urls import path from . import views urlpatterns = [ path('<page_slug>-<page_id>/history/', views.history), path('<page_slug>-<page_id>/edit/', views.edit), path('<page_slug>-<page_id>/discuss/', views.discuss), path('<page_slug>-<page_id>/permissions/', views.permissions), ] # 修改为: from django.urls import include, path from . import views urlpatterns = [ path('<page_slug>-<page_id>/', include([ path('history/', views.history), path('edit/', views.edit), path('discuss/', views.discuss), path('permissions/', views.permissions), ])), ]
-
传递捕获的参数
在主urls中配置:
urlpatterns = [ path('admin/', admin.site.urls), # 这里捕获username参数,类型为字符串 path('<username>/polls/', include('polls.urls')) ]
对应的 polls 应用下的urls中配置:
urlpatterns = [ path('arg_test/', views.arg_test), ]
对应的 polls 应用下的views中编写函数:
def arg_test(request, username): # 编写对应的业务逻辑 pass
9、额外的参数
from django.urls import path
from . import views
urlpatterns = [
# 会传递给 views.year_archive(request, year=2005, foo='bar')
path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}),
]
10、URL反向解析
url调度器除了从用户发起请求,到匹配对应的view,还能在python程序中调用进行匹配,通过 path或re_path 中 的name属性进行解析
- 在模板中,使用url模板标签
- 在Python代码中(主要是views),使用 reverse() 函数
- 在模型实例中,使用 get_absolute_url() 方法
示例:
urls中配置:
from django.urls import path
from . import views
urlpatterns = [
#...
path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
#...
]
- 在模板中
# 模板中:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
- 在python代码中
from django.urls import reverse
from django.http import HttpResponseRedirect
def redirect_to_year(request):
# ...
year = 2006
# ...
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
- 在模型中:
"""
在模型中实现方法:
def get_absolute_url(self):
from django.urls import reverse
return reverse('news-year-archive', args=[str(self.id)])
然后在 模板 中如下使用:
"""
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
11、命名空间
主要用于配合第 10 点 url反向解析 使用,多个不同的urls文件中可能配置同名的 name,那么为了进行区分,给不同的urls进行不同的命名,切记同一个项目下命名空间不能重复!
通过在 url调度器的模块中,定义 app_name = ‘polls’ 来命名
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'),
...
]
# 调用,一旦有了命名空间,调用时就必须使用 polls: 前缀
reverse('polls:index', current_app=self.request.resolver_match.namespace)
命名空间可以进行嵌套:
# 在 urls 中配置如下:
from django.urls import path
from . import views
# 定义命名空间,一般命名空间名和子应用名相同,便于记忆
app_name = 'polls'
extra_patterns = (
[
path('app_name/', views.app_name, name='app_name'),
],
# 此处就是嵌套的命名空间
'extra'
)
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('extra/', include(extra_patterns)),
...
]
# 在模板中使用:
<a href="{% url 'polls:extra:app_name' %}">点击链接</a>