URL映射
url分发映射配置可以被看作django项目的入口配置,通过url映射可以指定用户每一次访问的后台python处理函数是什么。
1. 普通url映射
- 每个项目都会维护一个urls.py的映射文件,如下: ```python from django.conf.urls import url from . import views
urlpatterns = [ url(r’^year/2020’, views.year_momnets), ]
b. 可以通过django.conf.urls.url()函数执行,第一个参数是HTTP路径,第二个参数是被映射到的函数名;
<a name="DdUGH"></a>
#### 2. 正则表达
1. 常见的正则表达式的语法法则:
| 符号 | 描述 | 举例 |
| :---: | :---: | :---: |
| \\ | 将下一个字符标记为特殊字符 | "\\n"匹配一个换行符;<br />"\\\\"匹配一个"\\" |
| ^ | 输入字符串的开始位置 | "^abc":以abc开头 |
| $ | 输入字符串的结束位置 | "abc$":以abc结尾 |
| * | 前面的子表达式零次或多次 | "2*"匹配"","2","222"等 |
| + | 前面的子表达式一次或多次 | "2+"匹配"2","222"等 |
| ? | 前面的子表达式零次或一次 | "2?"匹配"","2" |
| {n} | n是一个非负整数,只匹配确定的n次 | "o{2}"匹配"food"中的两个o |
| {n,} | n是一个非负整数,至少匹配n次 | "o{2,}"匹配"food","foood"等 |
| {n,m} | m和n均为非负整数,其中n<=m | "o{3,6}"匹配3~6个o |
| . | 匹配除"\\n"外的任意单个字符 | |
| x|y | 匹配x或y | "water|food"匹配water或者food |
| [xyz] | 字符集合,匹配所包含的任意一个字符 | [1, 2, 3]匹配"1"、"2"、"3" |
| [^xyz] | 负值字符集合,匹配未包含的任意字符 | |
| [-] | 字符范围 | "[e-h]"匹配"e"到"h"范围内的任意小写字符 |
| [^-] | 负值字符范围,匹配不在指定范围内的任意字符 | |
<a name="PNt6i"></a>
#### 3. 命名url参数映射
1. 命名url参数的定义方式是"**?P<param_name>pattern**"
```python
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^year/2020$', views.moments_2020),
url(r'^year/?P<year>([0-9]{4})/$', views.year_moments), # 调用year_moments(request, year=xxxx)
]
4. 分布式url映射
- 一个项目可包含多个django应用,每个应用都有自己的url映射规则,django提供了include()函数提供分布式url映射的功能,可在项目根目录映射文件xxx/urls.py中引用其他应用的url映射文件,如下: ```python from django.conf.urls import include, url
urlpatterns = [ url(r’^moment/‘, include(‘xxx.app.urls’)), # 以moment/开头的url被转接到xxx.app.urls包中,即xxx/app/urls.py文件 ]
被包含的子映射文件,如下:
```python
from django.conf.urls import include, url
urlpatterns = [
url(r'year/?P<year>([0-9]{4})/$',views.year_moments),
]
5. 反向解析
- 使用映射名代替很多需要写绝对url路径的地方,提高代码可读性。
- django的url反向解析功能在模板文件和python程序中使用,在模板文件中用{%url%}标签调用反向解析;在python程序中用django.urls.reverse()函数调用反向解析。
```python
定义url映射规则
from django.conf.urls import include, url
urlpatterns = [ url(r’^year/2020/$, views.year_moments, name = “moments_2020”), ]
```html
# 在模板中的应用
<a href="{%url 'moments_2020' %}">
查看2020年信息
</a>
# 解析结果为
#<a href="/year/2020/">
# 查看2020年信息
#</a>
# 在python程序中的应用
from django.urls import reverse
from django.http import HttpResponseRedirect
def redirect_to_year_2020(request):
return HttpResponseRedirect(reverse('moments_2020'))
6. 带参数的反向映射
- 反向解析支持在url路径和被调用函数中有参数的情况,如下:
- 其中用映射名”moments”和url参数2020作为反向解析的参数;
- 其中reverse()函数的args参数用于设置反向映射的url参数 ```python from django.conf.urls import include, url
urlpatterns = [
url(r’^year/?P
```html
# 在模板中的应用
<a href="{%url 'moments', 2020 %}">
查看2020年信息
</a>
# 解析结果为
#<a href="/year/2020/">
# 查看2020年信息
#</a>
# 在python程序中的应用
from django.urls import reverse
from django.http import HttpResponseRedirect
def redirect_to_year_2020(request):
return HttpResponseRedirect(reverse('moments', args=(2020,)))
视图函数
在通常情况下,视图函数的功能是通过模型层对象处理数据,然后用一下几种方式返回HTTP Response。
- 直接构造HTTP Body
- 用数据渲染HTML模板文件
- 如果有逻辑错误,则返回HTTP错误或者其他状态
1.直接构造http body
- 对于简单的页面,可以直接在视图函数中构造返回给客户端的字符串,通过HttpResponse()函数封装后返回 ```python from django.http import HttpResponse import datetime
def current_datetime(request): now = datetime.now().strftime(“%Y=%m-%d %H:%M:%S”) return HttpResponse(now)
<a name="LaxRS"></a>
#### 2.用数据渲染HTML模板文件
1. 模板渲染通过render()函数实现
1. 函数render()的第一个参数是HTTP request,第二个参数是模板文件名,第三个参数是以字典形式表达的模板参数
```python
from django.shortcuts import render
from app.models import Moment
def detail(request, moment_id):
m = Moment.objects.get(id=moment_id)
return render(request, 'templates/moment.html', {'headline':m.headline, 'user':m.user_name})
3.返回HTTP错误或者其他状态
- 通过给HttpResponse构造函数传递status参数,可以返回HTTP错误或者状态。
```python from django.http import HttpResponse
def my_status(request): return HttpResponse(status=404)
b. django中常用的HttpResponse子类:
1. HttpResponseRedirect:返回302,用于url重定向,需要将重定向的目标参数作为参数传入,经常使用reverse()函数,可避免修改网站url映射文件内容时维护视图函数代码;
1. HttpResponseNotModified:返回304,用于指示浏览器用其上次请求时的缓存结果作为页面内容展示;
1. HttpResponsePermanentRedirect:返回301,永久重定向;
1. HttpResponseBadRequest:返回400,请求内容错误;
1. HttpResponseForbidden:返回403,禁止访问错误;
1. HttpResponseNotAllowed:返回405,用不允许的方法;
1. HttpResponseServerError:返回500,服务器内部错误;
<a name="vB58o"></a>
### 模板语法
用模板的特殊语法用于替换动态内容
1. 其中{}包含的内容均为模板文件的特殊语法,其中{##}之间内容为注释内容
<a name="B4Cn1"></a>
#### 2. 变量替换
1. 用双大括号{{variable}}指示进行变量内容替换
```html
{% extends "base.html" %}
{% block title %}{{section.title}}{% endblock %} {#块内容, 用于模板继承#}
{% block content %}
<h1> {{section.title}}</h1> {#变量替换#}
{% for moment in moment_list %} {#流程控制--for循环#}
<h2>
{{moment.headline|upper}} {#带过滤器的变量替换#}
</h2>
{% endfor %}
{% endblock %}
{{moment.headline}} # 其中的moment是在视图函数渲染模板时传递给render()函数的参数之一。
3. 过滤器
- 过滤器(filter)在模板中是放在变量后并用于控制变量显示格式;
- 变量与过滤器之间通过管道符号”|”连接;
{{moment.headline | upper}} # 将upper过滤器应用在moment.headline变量中,其作用是指定大写方式输出
4. 流程控制
用{% for %}语句和{%if %}实现判断逻辑
{% for moment in moment_list %}
<h2>
{{ moment.headline|upper }}
</h2>
{% endfor %}
# 上述代码中的moment_list是视图文件传给模板渲染函数render()的列表参数
{% if moment.id < 10 %}
<h1> {{ moment.headline }} </h1>
{% elif moment.id < 20 %}
<h2> {{ moment.headline }} </h2>
{% else %}
<p>{{ moment.headline }}</p>
{% endif %}
5. 模板继承
- 父模板文件:保存公用部分
- 子模板文件:用于扩展父模板文件
子文件通过{%extends “父模板文件” %}标签指定父模板文件,通过{% block %}块重写需要覆盖父文件中的内容。