上一节学会了怎么使用 django 创建项目,以及创建app,这次学习在一个app中使用网页模版。
========
我们都知道,一个静态HTML网页就是一堆含有特殊含义字符串的组合,在django的HTML模版中,有如下语法规则:
变量的用法很简单,也和能基本,一个变量从context中输出一个值,这是一个类似字典的对象将键映射到值。
例子1:标准用法
比如在HTML模版中的文本使用如下写法:
我的名字是:{{ name }}
在视图函数中使用:
context={}
context['name'] = 'peter'
return render(request,'app/yourtemplates.html,context)
然后运行服务器展示该网页的时候就会显示: 我的名字是peter
例子2:字典索引以及函数使用
在HTML模版中写:
我的名字是:{{person.name.upper}},年龄为{{person.age}}
在视图函数中写:
person = {'name':'perter','age':'15'}
context={}
context['person'] = person
return render(request, 'blog/temp.html',context)
该模版就会显示 : 我的名字是:PERTER,年龄为15
注:该方法使用的是python中字符串的通用方法,并且可以套接使用,比如 {{person.name.lstrip.upper}} 意思就是去掉左边空格并大写,如果要使用自己写的方法详情可以百度 django 自定义模版函数….
标签在渲染过程中提供任意的逻辑。
这个定义有点含糊不清。例如,标签可以输出内容,用作例如控制结构。一个“if”语句或一个“for”循环,从数据库中获取内容,甚至可以访问其他模板标签。
标签被{%和%}包围,如下所示:
{%csrf_token%}
大多数标签接受参数:
{%cycle ‘odd’ ‘even’%}
一些标签需要开始和结束标签:
{%if user.is_authenticated%} Hello,{{user.username}}. {%endif%}
可以使用内置标签的参考以及编写自定义标签的说明,这里我列表出一些常用的标签:
标签 | 解释 |
{% for … %} ….{% endfor %} | 在第一个语句的for后面添加循环逻辑,中间写循环内容 |
{% if … %} …[…{% elif … %}…{% else %}…]..{% endif %} | 在第if和elif语句的后面添加判断逻辑,中间写判断内容.[]中的内容可选 |
{% ifequal .. ..%}…..{% endifequal %} | 在第ifequal后面比较两个值,如果相等则显示之间的所有值 |
{% block …%}…..{% endblock %} | 块标签,用于模版继承,继承该模版的模版都得实现该块中的内容 |
{% include …. %}td> | 包含标签,后面填写包含的.html,一般用于包含公共的页头/页尾/Logo等 |
{% extends … %} | 用于继承.html模版 |
过滤器转换变量和标记参数的值。
例子:
{{ name|lower }} //将变量变为小写
{{my_date | date:“Y-m-d”}} //改变时间显示格式
过滤器还可以套接 : {{ my_list|first|upper }} 等..
这里我列表出一些常用的过滤器: (引用自django架站16堂课)
名称 | 用途 | 示例 |
capfirst | 把第一个字母改为大写 | { {value|capfirst} } |
center | 把字符串内容居中 | { {value|center:”12”} } |
cut | 把字符串中指定的字符删除 | { {value|cut:” “} } |
date | 指定日期时间的输出格式 | { { value|date:”d M Y”} } |
linebreaksbr | 置换\n成为, |
{ {value|linebreaksbr} } |
linenumbers | 为每一行字符串加上行号 | { {value|linenumbers } } |
lower | 把字符串转换为小写 | { {value|lower } } |
random | 把前面的串行元素使用随机的方式任选一个输出 | { {value|random } } |
striptags | 把所有的HTML标记删除 | { {value|striptags } } |
truncatechars | 提取指定字数的字符 | { {value|truncatechars:40 } } |
upper | 把字符串转为大写 | { {value|upper } } |
wordcount | 计算字数 | { {value|wordcount } } |
{#这句话在django的HTML模版中会被忽略#}
{%comment%} 标记提供了多行注释
https://code.ziqiangxuetang.com/django/django-template2.html
关于模版的使用,我查阅资料,发现两种使用方式…
第一种,直接在当前APP文件夹中创建templates文件夹,在里面创建APP名的文件夹,再在里面创建模版,这种方式的优点是:当前APP的所有模版都在当前APP目录下,便于查找和使用。缺点是:如果好几个APP有一个共同的模版的话,虽然可以复用,但由于模版放在 templates/Appname 目录下,基模版文件只得放在工程根目录的templates下,文件比较分散。
Django 模板查找机制: Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。
在settings.py中的INSTALLED_APPS中添加APP的名字,然后在写视图函数的过程中就能直接通过 appname / temp.html的形式引用模版了,如下例:
def index(request):
a_list=['1','2','3','','4','5','6']
context={}
context['a_list'] = a_list
return render(request, 'blog/temp.html',context)
第二种,是在 django1.9的一本书上看到的,直接在工程根目录创建templates文件夹,然后在里面创建子文件夹和模版,再在setting.py中的TEMPLATES列表中添加该目录:
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',
],
},
},
]
在这添加模版目录后就可以在视图函数中这样引用了:
from django.shortcuts import render #render 引用模版html 可以发送字典参数(模版context实例化)
from django.http import HttpResponse
from .forms import AddForm
from django.template.loader import get_template # 可以从setting.py中设置的template位置中获取模版文件
# locals()函数,把当前内存中所有的局部变量使用字典类型打包起来,可以把这玩意传送给render作为模版中的值
def homepage(request):
template = get_template('index.html')
posts = Post.object.all() #从模型函数中的post对象获取全部对象
now = datetime.now() #获取当前时间
html = template.render(locals())
return HttpResponse(html)
django中的模板的确是好用的东西,但很多标签,过滤器不大符合习惯,或者找不到自己需要的,这时候就得自定义模板标签以及过滤器了。
自定义标签和过滤器必须依赖于一个django app,也就是说,自定义标签和过滤器是绑定app的。该app应该包含一个templatetags目录,这个目录一个和model.py,views.py在同一个层级,记得在该目录下建立一个init.py文件一遍django知道这是一个python包。例子如下:
from django import template
from django.utils.safestring import mark_safe #mark_safe函数能使html字符进行转义
register = template.Library() #获取模板装饰器
######################定义过滤器####################
@register.filter
def filter_multi(context, v1): #定义一个过滤器最多只能有一个参数
return context * v1
######################定义标签#####################
@register.simple_tag
def simple_tag_multi(context, v1): #定义标签能有多个参数 使用为{% %}
return context * v1
使用方法为:
1.在需要使用该标签的template中使用{% load my_tag %}
template.html <- 文件名
{% load my_tag %}
关于自定义标签,更详细的文档请参考:
https://www.cnblogs.com/qwj-sysu/p/4246605.html
参考:
https://docs.djangoproject.com/zh-hans/2.0/topics/templates/
https://code.ziqiangxuetang.com/django/django-template.html
https://www.cnblogs.com/sxh-myblogs/p/7724814.html
Django架站的16堂课