# Django-Learning
**Repository Path**: simonck666/django-learning
## Basic Information
- **Project Name**: Django-Learning
- **Description**: Django Learning
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-05-07
- **Last Updated**: 2021-05-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Django
## 1. Django 简介
### 1.1 组件
- 基本配置文件 / 路由系统
- 模型层(M)[Database] / 模板层(T)[html] / 视图层(V)[request]
- Cookies & Session
- 分页及发邮件
- Admin 管理后台
#### 用途
- 网站
- 微信公众号
- 小程序后端开发
> 浏览器 --> request --> Django
- 人工智能
> Django 官网:https://www.djangoproject.com/
> Django 中文:https://www.django.cn/
> 中文文档开发:https://yiyibooks.cn/
### 1.2 Django 版本
- 最新版:3.x
- 使用版:2.2
> LTS: long-term support 长期支持版 2.2 2019version
### 1.3 配置环境
```sh
// 安装
sudo pip install django==2.2.12
// 检查是否安装成功
sudo pip freeze|grep -i 'Django'
```
### 1.4 创建项目
```sh
// create a project
django-admin startproject xxx
```
### 1.5 启动服务(测试开发)
```sh
cd mysite1
python manage.py runserver
python manage.py runserver 5000 // 指定端口号
```
> 默认 8000 端口
### 1.6 关闭服务(测试开发)
- 在 runserver 终端下:`Ctrl + c`
- 其他终端下:
```sh
// find port 8000
sudo lsof -i:8000
// finish server
kill -9 xxx
```
### 1.7 项目框架
- manage.py 项目管理子命令
```sh
启动服务
python manage.py runserver
创建应用
python manage.py startapp
数据库迁移
python manage.py migrate
```
> `python manage.py` :所有Django子命令
- mysite1/mysite1 项目同名文件夹
- `__init__`: Python 包的初始化文件
- `wsgi.py`:WEB 服务网关配置文件,Django正式启动需要用到(**上线**)
- `urls.py`:项目主路由配置 - HTTP请求进入Django时,优先调用该文件
- `settings.py`:项目配置文件 - 包含项目启动时需要的配置
- 配置项:公有配置 和 自定义配置
- 配置项格式:`BASE_DIR = 'xxxx`
- 公有配置 - Django 官方提供的基础配置
- https://docs.djangoproject.com/zh-hans/2.2/topics/settings/
### 1.8 settings.py 分析
```python
# 项目绝对路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# settings.py 绝对路径
os.path.abspath(__file__)
# mysite1 路径
os.path.dirname(os.path.abspath(__file__))
```
```python
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
'''
1. True:调试模式
1.1 检测代码改动之后,立刻重启服务
1.2 报错界面
2. False:正式启动模式 / 上线模式
'''
```
```python
# 请求头
ALLOWED_HOSTS = []
'''
上线模式下进行配置请求头:具体域名
'''
```
- 如果进行内网穿透:必须在同一个局域网中
```python
python manage.py renserver 0.0.0.0:5000
// 指定网络设备如果内网环境下其他主机正常访问该站点,需加 ALLOWED_HOSTS = ['内网ip']
// 查询内网 ip:
ifconfig
```
```python
# 访问主路由
ROOT_URLCONF = 'mysite1.urls'
```
```python
# html
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
```
```python
# 语言:默认英文
LANGUAGE_CODE = 'en-us'
# 改为中文
LANGUAGE_CODE = 'zh-Hans'
# 默认时间:格林尼治
TIME_ZONE = 'UTC'
# 中国时间:中 8:
TIME_ZONE = 'Asia/ShangHai'
```
## 2. URL 和 视图函数
### 2.1 URL
- 定义:统一资源定位符 Uniform Resource Locator
- 作用:用来表示互联网上某个资源的地址
- 语法:
- `protocol://hostname[:port]/path[?query][#fragment]`
- `protocol`:协议:http, https
- `hostname`:域名
- `[:port]:`:端口:可有可无
- `path`:**路由:具体访问网站下某个部分的内容**
- `[?query]`:查询字符串:给 Django 带来数据
- `[#fragment]`:锚点:定位到 html 中的某个点
### 2.2 Django 如何处理 URL 请求
#### 处理 URL 请求
- 浏览器地址栏:http://127.0.0.1:8000/page/2003/
1. Django 从配置文件中 根据 ROOT_URLCONF 找到 **主路由** 文件;默认情况下,该文件在**项目同名目录下的 `urls`**, E.g.: `mysite1/mysite1/urls.py`
2. Django 加载主路由文件中的 `urlpatterns` 变量 [包含很多路由的数组]
3. 一次匹配 `urlpatterns` 中的 `path`,匹配到**第一个值**后**中断后续匹配**
4. 匹配成功:调用对应的视图函数处理请求,返回相应
5. 匹配失败:返回 404 响应
```python
# mysite1/mysite1/urls.py
"""mysite1 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
# 调用 views.py 中的视图函数
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
# http://127.0.0.1:8000/page/2003
path('page/2003', views.page_2003_view) # 视图函数为下面的视图函数
]
```
#### 视图函数
- 视图函数是用于接收一个浏览器请求(HttpRequest 对象)并通过 HttpResponse 对象返回相应的函数。次函数可以接收浏览器请求并根据业务逻辑返回相应的响应内容给浏览器
- 语法:
```python
# mysite1/mysite1/views.py
import django.http import HttpResponse
def xxx_view(request, [其他参数]):
return HttpResponse 对象
```
```python
# mysite1/mysite1/views.py
import django.http import HttpResponse
def page_2003_view(request):
html = "
First Page
"
return HttpResponse(html)
```
## 3. 路由配置
### 3.1 路由配置
- settings.py 中的 `ROOT_URLCONF` 指定了主路由配置列表 `urlpatterns` 的文件位置
```python
# file: <项目同名文件夹下>/urls.py
urlpatterns = [
path('/page/2003/', views.page_2003_view),
... # 此处配置主路由
]
```
- path 函数
1. 导入 - `from django.urls import path`
2. 语法 - `path(route, views, name=None)`
- route:字符串类型,匹配的请求路径
- views:指定路径所对应的视图处理函数的名称 **ps: 不要在函数后加()**
- name:为地址起别名,在模板中地址反向解析时使用
- path 转换器
1. 语法:`<转换器类型:自定义名>`
2. 作用:若转换器类型匹配到对应类型的数据,则将数据按照关键字传参的方式传递给视图函数
3. 例子:`path('page/', views.xxx)`
4. 转换器类型:
- str:匹配除了 '/' 之外的非空字符串
- int:匹配 0 或任何正整数。返回一个 int
- slug:匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签
- path:匹配非空字段,包括路径分隔符 '/'
```python
# file: <项目同名文件夹下>/urls.py
urlpatterns = [
# http://127.0.0.1:8000/page/3-100
path('page/', views.pagen_view)
... # 此处配置主路由
]
```
```python
# file: <项目同名文件夹下>/views.py
def page_view(request, pg):
html = "Item %s." % (pg)
return HttpResponse(html)
```
- re_path() 函数
1. 在 url 配置过程中可以使用正则表达式进行精确匹配
2. 语法:
- `re_path(reg, view, name=xxx)`
- 正则表达式为命名分组模式`(?Ppattern)`;匹配提取参数后用关键字传参方式传递给视图函数
## 4. 请求与响应
### 4.1 定义
- 请求时指浏览器端通过 HTTP 协议发送给服务器端的数据
```sh
// 请求样例 Headers
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Host: 127.0.0.1:8000
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36
```
1. 请求方法
- GET:请求指定的页面信息,并返回实体主体
- HEAD:类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改
- PUT:更新数据
- DELETE:删除
- CONNECT:翻墙
- OPTIONS:查看服务器性能
- TRACE:回显服务器收到的请求,主要用于测试或诊断
2. Django 中的请求
- 实例:视图函数中的第一个参数,即 HttpRequest 对象
- Django 收到 http 协议的请求后,会根据请求数据报文创建 HttpRequest 对象
- HttpRequest 对象 通过属性 描述了请求的所有相关信息
- 示例:
- `path_info`: URL 字符串
- `method`:字符串,表示 HTTP 请求方法,常用值:'GET', 'POST'
- `GET`:QueryDict 查询字典的对象,包含 GET 请求方式的所有数据
- `Post`:QueryDict 查询字典的对象,包含 POST 请求方式的所有数据
- `FILES`:类似于字典的对象,包含所有的上传文件信息
- `COOKIES`
- `session`
- `request.get_full_path()`:请求的完整路径
- `request.META`:请求的元数据(消息头)
- `request.META['REMOTE_ADDR']`:客户端 IP
```python
# file: <项目同名文件夹下>/urls.py
urlpatterns = [
path('test_request', views.test_request)
]
```
```python
# file: <项目同名文件夹下>/views.py
def test_request(request):
print('path info is ', request.path_info)
print('method is ', request.method)
print('querystring is ', request.GET)
return HttpResponse('test request ok')
```
> 终端中得到:
> path info is /test_request
> method is GET
- 响应是指服务器端接受到请求后做相应的处理后再回复给浏览器端的数据
```sh
// HEADER
Content-Length: 10
Content-Type: text/html; charset=utf-8
Date: Sat, 08 May 2021 00:43:25 GMT
Server: WSGIServer/0.2 CPython/3.9.4
X-Frame-Options: SAMEORIGIN
```
1. 响应状态码
HTTP 状态码:HTTP Status Code
- 200 - 请求成功
- 301 - 永久重定向 - 资源(网页等)被永久转移到其他 URL
- 更换域名
- 302 - 临时重定向
- 登录页面登录后跳转
- 404 - 请求的资源(网页等)不存在
- 500 - 内部服务器错误
2. 响应状态码分类
- 1**:信息,服务器收到请求,需要请求这继续执行操作
- 2**:成功,操作被成功接收并处理
- 3**:重定向,需要进一步的操作以完成请求
- 4**:客户端错误,请求包含语法错误或无法完成请求
- 5**:服务器错误,服务器再处理请求的过程中发生错误
3. Django 中的响应对象
- 构造函数格式:
```python
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
```
- 作用:向客户端浏览器返回响应,同时携带响应体内容
3. Content-Type
- 'text/html'
- 'text/plain':纯文本
- 'text/css'
- 'text/javascript'
- 'multipart/form-data':文件提交
- 'application/json':json 传输
- 'application/xml':xml 文件
### 4.3 GET & POST
#### 4.3.1 定义
- 无论是 GET 还是 POST,统一都由视图函数接收请求,通过判断 `request.method` 区分具体请求
```python
# 样例
if request.method == 'GET':
处理 GET 请求时的业务逻辑
elif request.method == 'POST':
处理 POST 请求时的业务逻辑
else:
其他请求业务逻辑
```
```python
# views.py
def test_get_post(request):
if request.method == 'GET':
pass
elif request.method == 'POST':
# do the function
pass
else:
pass
return HttpResponse('--test get post is ok')
```
#### 4.3.2 GET 处理
- GET 请求动作,一般用于向服务器**获取数据**
- 能够产生 GET 请求的场景
- 浏览器地址栏输入 URL,回车后
- ``
- 当 form 表单中的 method 为 GET
- GET 请求中,如果由数据需要传递给服务器,通常会用查询字符串(Query String)传递
- URL:xxx?参数名1=值1&参数名2=值2
- 服务器端接收参数
- 获取客户端请求 GET 请求提交的数据
```python
# views.py
def test_get_post(request):
if request.method == 'GET':
print(request.GET['a'])
# recognize
print(request.GET.get('c', 'no c'))
# 问卷调查 - form get请求写的 - 兴趣爱好(复选框)
print(request.GET.getlist('a')
elif request.method == 'POST':
# do the function
pass
else:
pass
return HttpResponse('--test get post is ok')
```
#### 4.3.3 POST 处理
- POST 请求动作,一般用于向服务器**提交大量 / 隐私数据**
- 客户端通过表单等 POST 请求将数据传递给服务器端,如:
```html
```
> 表单提交之后,key 就是 `name=`,value 就是用户输入的东西
- 服务器端接收参数
- 通过 `request.method` 来判断是否为 POST 请求
```python
if requesst.method == 'POST':
处理 POST 请求的数据并响应
else:
处理非 POST 请求的响应
```
```python
if requesst.method == 'POST':
print(request.POST['a']) # request.POST 绑定 QueryDict
print(request.POST.get('c', 'no c'))
print(request.POST.getlist('a')
else:
处理非 POST 请求的响应
```
> **取消 `csrf` 验证,否则 Django 将会拒绝客户端发来的 POST 请求,报 403 响应**
- 取消 `csrf` 验证
- 禁止 `settings.py` 中 `MIDDLEWARE` 中的 `CsrfViewsMiddleWare` 的中间件
```python
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',
...
]
```
> 可能会发生 `csrf` 攻击
```python
# views.py
def test_get_post(request):
if request.method == 'GET':
# print(request.GET['a'])
print(request.GET.get('c', 'no c'))
return HttpResponse(POST_FORM)
elif request.method == 'POST':
# do the function
print('uname is ', request.POST['uname'])
return HttpResponse('post is ok')
else:
pass
return HttpResponse('--test get post is ok')
```
```python
# urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('test_get_post', views.test_get_post)
]
```
## 5. Django 的设计模式及模板层
### 5.1 MVC & MTV
#### 5.1.1 传统 MVC
- MVC:Model-View-Controller (模型-视图-控制器)模式
- M:用于对数据库层的封装
- V:用于向用户展示结果 (WHAT + HOW)
- C:用于处理请求,获取数据,**返回结果**
> 降低模块之间的耦合度
#### 5.1.2 Django 的 MTV 模式
- MTV:Model-Template-View
- M:与数据库交互
- T:模板层负责呈现内容到浏览器(HOW)
- V:视图层是**核心**,负责接收请求,获取数据,**返回结果**(WHAT)
### 5.2 模板层(template)
1. 模板是可以根据字典数据动态变化的 HTML 网页
2. 模板可以根据视图中传递的字典数据动态生成响应的 HTML 网页
#### 5.2.1 模板配置
创建模板文件夹 <项目名>/templates
在 `settings.py` 中 TEMPLATES 配置项:
1. BACKEND:指定模板的引擎
2. DIRS:模板的搜索目录(可以使一个或多个)
3. APP_DIRS:是否要在应用中的 templates 文件夹中搜索模板文件
4. OPTIONS:有关模板的选项
- 配置项中需要修改的部分
- 设置 DIRS
```python
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',
],
},
},
]
```
#### 5.2.2 模板加载
##### 5.2.2.1 方案 1
通过 `loader` 获取模板,通过 `HttpResponse` 进行响应
```python
# in the views.py function
from django.template import loader
# 1. 通过 loader 加载模板
t = loader.get_template("模板文件名")
# 2. 将 t 转换成 HTML 字符串
html = t.render(字典数据)
# 3. 用响应对象将转换的字符串内容返回给浏览器
return HttpResponse(html)
```
- 实例
```python
# views.py
def test_html(request):
from django.template import loader
t = loader.get_template('test_html.html')
html = t.render()
return HttpResponse(html)
```
```html
Title
In Template....
```
```python
# urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('test_html', views.test_html)
]
```
##### 5.2.2.2 方案 2
使用 `render()` 直接加载并响应模板
```python
# in views.py function
from django.shortcuts import render
return render(request, '模板文件名', 字典数据)
```
#### 5.2.3 视图层与模板层之间的交互
1. 视图函数中可以将 Python 变量封装到**字典**中传递到模板
```python
def xxx_view(request):
dic = {
"key1":"val1",
"key2":"val2"
}
return render(request, 'xxx.html', dic)
```
2. 模板中,我们可以用 `{{ 变量名 }}` 的语法调用视图层换进来的变量
#### 5.2.4 模板层 - 变量
视图函数中可以将 Python 变量封装到**字典**中传递到模板上
```python
def xxx_view(request):
dic = {
"key1":"val1",
"key2":"val2"
}
return render(request, 'xxx.html', dic)
```
1. 能传递到模板中的数据类型
- str
- int
- list
- tuple
- dict
- func
- obj - 实例化对象
2. 模板中使用变量语法
- {{ varname }}
- {{ varname.index }} -- list
- {{ varname.key }} -- dict
- {{ obj.func }} -- obj *不需要函数之后的`()`*
- {{ funcname }}
#### 5.2.4 模板层 - 标签
1. 作用:将一些服务器端的功能嵌入到模板中,例如:流程控制等
2. 语法:
```html
{% 标签 %}
...
{% end 标签 %}
```
3. if 标签
```html
{% if expression1 %}
...
{% elif expression2 %}
...
{% else %}
...
{% endif %}
```
> P.s. :在 if 标记中**无法使用实际括号**来表明优先级,需要使用**嵌套 if** 来表明优先级
4. if 标签实例 —— 计算器
```html
# test_mycal.html
Title
```
```python
# views.py
from django.http import HttpResponse
from django.shortcuts import render
def test_mycal(request):
if request.method == 'GET':
return render(request, "mycal.html")
elif request.method == 'POST':
# deal with cal
x = int(request.POST['x'])
y = int(request.POST['y'])
op = request.POST['op']
if op == 'add':
result = x + y
elif op == 'sub':
result = x - y
elif op == 'mul':
result = x * y
elif op == 'div':
result = x / y
# locals() equal to 帮我们封装函数中的局部变量为一个字典
# dic = {'x':x, 'y':y, 'op':op}
return render(request, "mycal.html", locals())
```
```python
# urls.py
"""mysite1 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('mycal', views.test_mycal)
]
```
5. for 标签
```python
{% for 变量 in 可迭代对象 %}
... 循环语句
{% empty %}
... 可迭代对象无数据时填充的语句
{% enfor %}
```
- 内置变量 forloop
- forloop,counter:循环的当前迭代(从1开始索引)
- forloop.counter():循环的当前迭代(从0开始索引)
- forloop.revcounter:counter 值的倒序
- forloop.recounter0:recounter 值的倒序
- forloop.first:如果这是第一次通过循环则为真
- forloop.last:如果这是最后一次通过循环则为真
- forloop.parentloop:当嵌套循环,parentloop 表示外层循环
#### 5.2.5 模板层 - 过滤器与继承
1. 过滤器
- 定义:在变量输出时对变量的值进行处理
- 作用:可以通过使用过滤器来改变变量的输出显示
- 语法:
```python
{{ 变量|过滤器1:'参数值1'|过滤器2:'参数值2'... }}
```
- 常用过滤器
- lower:字符串转为全部小写
- upper:字符串转为全部大写
- safe:默认不对变量内的字符串进行 html转义
- add:"n":将 value 值增加 n
- truncatechars:'n':如果字符串字符多余指定的字符数量,那么会被拦截。拦截的字符串将以可翻译的省略号序列 ("...") 结尾
2. 继承
- 定义:模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块
- 语法 - 父模板中:
- 定义父模板中的块 block 标签
- 标识出哪些在子摸块中是允许被修改的
- block 标签:在父模板中定义,可以在子模板中覆盖
- 语法 - 子模板中:
- 继承模板 extends 标签(写在模板文件的第一行)
- 例如:`{% extends 'base.html' %}`
- 子模板:重写父模板中的内容块
```html
{% block block_name %}
子模板用来覆盖父模板中 block_name 块的内容
{% endblock block_name %}
```
- 重写的覆盖规则
- 不重写:将按照父模板的效果展示
- 重写,则按照重写效果展示
- 注意
- 模板继承时,**服务器端的动态内容无法继承**
## 6. URL 反向解析
### 6.1 再看 URL
1. 代码中 URL 出现的位置
- 模板 [ html ] 中
- `````` form 表单中的数据,用 POST 方法提交至 URL
- 视图函数中 - 302 跳转:```HttpResponseRedirect('url')```:将用户地址栏中的地址跳转到 URL
2. 代码中 URL 书写规范
- 绝对地址:`http://127.0.0.1/page/1`
- 相对地址:`1` 、`/page/1`
- `/` 开头的相对地址,浏览器会把当前地址栏里边的协议,ip 和端口加上这个地址,作为最终访问地址,即如果当前页面地址栏为 `http://127.0.0.1/page/3`; 当前相对地址最终结果为:`http://127.0.0.1:8000` + `/page/1`
- **没有 `/` 开头的相对地址**:浏览器会根据当前 URL 的最后一个 `/` 之前的内容加上该相对地址作为最终访问地址。例如,当前地址栏中地址为:`http://127.0.0.1/topic/detail`;则该相对地址最终结果为:`http://127.0.0.1/topic/` + `page/1`
3. URL 反向解析
URL 反向解析是指在视图或模板中,用 path 定义的名称来**动态查找或计算出相应的路由**
- path 函数的语法
- `path(route, views, name="别名")`
- E.g.: `path('page', views.page_view, name="page_url")`
- 根据 path 中的 `name=` 关键字传参给 URL 确定了唯一确定的名字,在模板或视图中,可以通过这个名字反向推断出此 URL 信息
- 模板中 - 通过 URL 标签实现地址的反向解析
```python
{% url '别名' %}
{% url '别名' '参数值1' '参数值2' %}
e.g.:
{% url 'pagen' '400' %}
{% url 'person' age='18' name='gxn' %}
```
```html
Title
url
```
- 视图函数中 - 可调用 Django 中的 reverse 方法进行反向解析
```python
from django.urls import reverse
reverse('别名', args=[]. kwargs=[])
e.g.:
print(reverse('pagen', args=[300]))
print(reverse('person', kwargs={'name':'xixi', 'age':18}))
```
## 7. 静态文件
### 7.1 什么是静态文件
静态文件:css,js,video,image,audio
### 7.2 静态文件配置
- 静态文件配置 - settings.py 中
1. 配置静态文件的访问路径 [该配置默认存在]
- 通过哪个 URL 地址找静态文件
- `STATCIC_URL = '/static/'`
- 说明:
- 指定访问静态文件时需要通过 /static/xxx 或 http://127.0.0.1/static/xxx
2. 配置静态文件的存储路径 STATICFILES_DIRS
STATICFILES_DIRS 保存的是静态文件在服务器端的存储位置
```python
# file: setting.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
```
3. 静态文件访问 - img 标签为例
- 传统路径访问
- 通过 `{% static %}` 标签访问静态文件
1. 加载 static - {% load static %}
2. 使用静态资源 - {% static '静态资源路径' %}
3. 样例 ```![]()