* 自定义路径转化器
* 模板
* 模板参数
* 模板常用的标签
## 复习
```
from django.http import HttpResponse
def index(request):
return HttpResponse()
http://127.0.0.1:9000/book
主目录的urls.py
from django.urls import path
from book import views
urlpatterns = [
path('book/',views.book),
]
在url 中添加参数
http://127.0.0.1:9000/book/detail/18
urls.py
urlpatterns = [
path('book/detail/<int:book_id>/<>',views.book),
]
views.py
def book_detail(request,book_id,ids_id):
username = request.GET.get('')
text = " %s %s" % (book_id,ids_id)
return HttpResponse(text)
re_path
from django.urls import re_path
urlpatterns = [
re_path(r'^book/(?P<age>[0-9]{4})/$',views.book),
]
redirect('/login/')
urlpatterns = [
path('',views.page),
path('book/page/<int:num>',view.page)
]
def page(request,num=1):
return
```
## 需求:
```
1.要求获取python分类下的文章
articles/python
2.要求获取python+django 分类下的文章
articles/python+django/
3.要求获取python+django+flask 分类下的文章
articles/python+django+flask/
urlpatterns = [
path('',views.article),
#/article/list/python+django+flask
#baidu|google|so
re_path(r'list/(?P<categories>\w+|(\w+\+\w+)+)/',views.article_list)
]
```
### 自定义 path 转化器
```
需求2:
将 python+django+flask传递到 视图函数(article_list(request)) 变成 ['python','django','flask']
浏览器提交到服务器 服务器从 数组中解析 categories:['python', 'django', 'flask', 'linux']
在使用 url反转的时候 将 ['python','django','flask'] 变成 python+django+flask 从服务器显示到浏览器 默认让用户跳转到 article/list/python+django+flask+linux/
vim 应用下面新建一个 converters.py
from django.urls import converters,register_converter
class CategoryConverter(object):
regex = r'\w+|(\w+\+\w+)+'
def to_python(self, value):
#当你把django+flask 传过来的时候 value 来接收
result = value.split("+") # ['python','django']
return result
def to_url(self, value):
# value [['python','django']]
if isinstance(value,list):
result = "+".join(value)
return result
else:
raise RuntimeError("转化的url参数必须是列表")
register_converter(CategoryConverter,'cate') 别忘了注册 要不然这个类 不被调用
应用下面的 __init__.py
from . import converters
vim 应用下面的 urls.py
path('list/<cate:categories>/',views.article_list,name='list')
```
## 模板
> 上几节课 我们 直接返回的是文本 生产环境 页面需要样式 为了让 页面漂亮 市场上 好多不错 模板系统
>
> 其中就有 DTL jinja2 django 默认自带 DTL
**DTL django template language ** 模板引擎
DTL 和 html的区别 :
DTL 是由特殊语法的html 会解析参数 让页面更加动态化 编译完成以后 生成一个普通的html文件 然后发给客户端
> render_to_string 先找到 模板 (页面) 将模板编译以后将内容渲染成python字符串格式 然后通过 HttpResponse 类 包装成 一个 HttpResponse 对象 返回给 前台
```
from django.shortcuts import render
from django.http import HttpResponse
from django.template.loader import render_to_string
# Create your views here.
def index(request):
html = render_to_string(‘index.html’)
return HttpResponse(html )
#以上可能有点繁琐
from django.shortcuts import render
def index(request):
return render(request,'index.html')
```
### 模板查找路径配置
```
settings.py 中有一个 TEMPLATES 配置
BASE_DIR 你的项目目录
'DIRS': [os.path.join(BASE_DIR, 'templates')] 项目目录下templates文件夹
也就是说 render render_to_string 会来这里 查找模板
#'DIRS': [r"C:\templates"] 可以自定义主 templates 文件夹位置
'APP_DIRS': True, 要记得 在 settings.py中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'book' #加入你创建的应用 要不然找不到这个模板
]
APP_DIRS 为true 先到 app 应用下面的 templates 查找 没有 到 主目录下面
Flase 直到 主目录下面 templates文件下查找 页面
1.先到应用自己的目录下面的 templates
2.如果自己目录没有 到其它应用 templates 下
3.其它应用也没有 到主目录下面templates 下
4,全部没有 抛异常 templatedoesnotexists 异常
如果 为 false 不从应用下面找 直接从主目录下 templates下查找
顺序:
render(request,‘home.html’)
先到 DIRS 有就返回 没有 到自己的应用 templates下面 别忘了应用加入到 INSTALLED_APPS 如果有 返回
如果没有 到 其它已经安装的应用下面 templates文件夹下
都没有 抛异常 templatedoesnotexists 异常
```
## IDE
* pycharm
* sublime
* atom
* hbuilder
## django 模板常用的变量
```
1.在模板中使用变量 需要将其放入 {{变量 }}
# haha = {
# 'username':'兰陵笑笑生',
# 'age':18
# }
{{username }}
2.访问对象的属性 对象.属性名来访问
class Person(object):
def __init__(self,username):
self.username = username
qulinx = Person("秋林兄")
# haha ={
# 'person':qulinx
# }
{{person.username}}
3.访问字典对应的value值 字典.key 不能通过[]访问
contexts = {
# 'person':{
# 'username':'qulinx666',
# 'keys':'abc' 尽量不要使用 keys 作为key
#
# }
# }
{{person.username}}
4.访问 元组 或者列表
contexts = {
'person':[
'红楼梦',
'三国演义',
'西游记',
'水浒传',
]
}
{{person.0}} #红楼梦
```
## django 模板常用的标签
```
所有的标签都是在{% 中 %}
if 判断条件 == != < <= > >= in not in is is not
if有关闭标签 {% endif %} 因为模板不像python 有缩进 必须要有关闭
elif
else
举例子
context = {
'age':18
}
return render(request,'index.html',context=context)
{% if age < 18 %}
<p>您还没成年,不能大宝剑</p>
{% elif age == 18 %}
<p>您满18周岁了 可以进来了</p>
{% else %}
<p>虽然你成年了但是大宝剑不是想有就有的</p>
{% endif %}
{% if '雷鸣兄' in Tokyo %}
<p>雷鸣兄正在工作</p>
{% else %}
<p>雷鸣兄正在待命</p>
{% endif %}
```
## for in 类似于python 中的 for...in...
* 元组
* 字典
* 列表
* 字符串等
```
{% for book in books %} 正序遍历
<li>{{ book }}</li>
{% endfor %}
{% for book in books reversed%} 倒序遍历
<li>{{ book }}</li>
{% endfor %}
{% for book in books %}
<tr>
<td>{{ forloop.counter0 }}</td>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
forloop.counter 当前循环的下标 以 1开始
forloop.counter0 当前循环的下标 以 0开始
forloop.revcounter
forloop.revcounter0
forloop.first 是否第一次遍历 第一行
forloop.last 是否是最后一次遍历 最后一行
forloop.parentloop 多个循环嵌套的情况下 这个表示上一个for
<tbody>
{% for book in books %}
{% if forloop.first %}
<tr style="background: pink">
{% elif forloop.last %}
<tr style="background: green">
{% else %}
<tr>
{% endif %}
<td>{{ forloop.counter }}</td>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
遍历的对象没有任何元素的情况下 用{%empty%} 去匹配 显示 默认内容
比如
<ul>
{% for content in contents %}
<li>{{ content }}</li>
{% empty %}
<li>暂时没有任何人评论赶紧抢沙发</li>
{% endfor %}
</ul>
遍历字典 ‘items’ ‘keys’ ‘values’
'person':{
'username':'zelinx',
'sanwei':'18 80 100',
'height':'181cm',
}
<ul>
{% for key in person.keys %}
<li>{{ key }}</li>
{% endfor %}
</ul>
<ul>
{% for key in person.values %}
<li>{{ key }}</li>
{% endfor %}
</ul>
{% for key,value in person.items %}
<p>{{ key }}</p>
<p>{{ value }}</p>
{% endfor %}
```
## autoescape 标签
```
自动转义 DTL 自动开启了转移 < < 比如
<a href='http://www.baidu.com'>百度大叔</a>
<a href='http://www.baidu.com'>百度大叔</a>
你要是不清楚自己相干什么的情况下 最好是 开启 自动转移 防止XSS漏洞攻击
如果变量完全信任 那么可以 关闭自动 转移
{% autoescape off %}
变量
{% endautoescape %}
{% autoescape on %}
{{ info }}
{% endautoescape %}
<a href="http://www.qfedu.com">qianfeng</a>
```
## url 标签
```
url 标签 因为 我们跳转的url 不能写死 最好是 通过反转的形式 跟 reverse 差不多
具体写法
<li><a href="{% url 'book' %}">读书</a></li>
<li><a href="{% url 'city' %}">同城</a></li>
<li><a href="{% url 'movie' %}">电影</a></li>
book city movie 都是 url的名字
path('book/',views.book,name='book'), 先根据 name 将url反转也就是 取出 /book/然后交给 index.html
path('movie/',views.movie,name='movie'),
path('city/',views.city,name='city'),
如果 跳转 需要添加参数
python:
path('book/detail/<book_id>/<category>/',views.book_detail,name='detail'),
DTL:
<li><a href="{% url 'detail' book_id=1 %}">转发锦鲤转给属龙的人</a></li>
传递参数
空格 隔开 即可
<li><a href="{% url 'detail' book_id=1 category=2 %}">转发锦鲤转给属龙的人</a></li>
加 ?next 查询字符串的形式
<li><a href="{% url 'login' %}?next=/">登陆</a></li>
```