Django之模板&静态文件(一)
- 补充: html链接的相对路径与绝对路径
- 绝对路径
完整的一个路径就是绝对路径,即包含schema://host[:port#]/path/.../[?query-string][#anchor]
例:http://news.sina.com.cn/world/
2.相对路径
第一个字符为斜杠/
例:“/hello”, 这种会自动帮你添加你的协议名+域名+端口, 假设你的前一节为http://www.baidu.com:8000, 系统会自动匹配为"http://www.baidu.com:8000/hello" (我们实际情况中一般使用这种)
第一个字符不带斜杠
例:“hello”, 这种会在当前url中path段往后添加,假设你当前路径http://www.baidu.com:8000/hello, 系统会自动匹配为“http://www.baidu.com:8000/hello/hello, ”
-
settings中模板路径配置
settings.py中配置 image.png
-
使用构建html网页
#主urls.py
url(r'^test/',include('TestApp.urls'))
#应用urls.py
url(r'^visit/$',views.Visit.as_view())
#views.py
class Visit(View):
def get(self,request):
return HttpResponse('<h1>使用直接将html字符串硬编码到HttpResponse中。</h1>')
image.png
- 使用render进行渲染
#应用urls.py
url(r'^visit/$',views.Visit.as_view())
#views.py中用render关联html文件
from django.shortcuts import render,redirect
class Visit(View):
def get(self,request):
#这个路径是一个相对路径,类似url路径规则,但是它是从你配置TEMPLATES文件夹开始的,
#这里配置的是根目录下的template文件夹,这里的相对路径第一个字符,不需要添加/
return render(request,'render.html')
#在templates下建立一个html文件render.html
.....
image.png
- 使用django.template.loader下的get_template方法进行渲染。(进阶用法,了解即可)
#views.py
from django.template.loader import get_template
class Visit(View):
def get(self,request):
t = get_template('testTemplate/get_template.html')
return HttpResponse(t.render())
#templates/testTemplate下新建html文件
- 模板引擎
- Django自带了一个模板系统,叫做DTL(Django Template Language)。
- 一个比较流行的模板系统,叫做Jinja2
- 配置:可以在settings文件中的TEMPLATES->BACKEND进行配置,默认使用的是django自带的DTL。配置DTL:'BACKEND': django.template.backends.django.DjangoTemplates',配置Jinja2:django.template.backends.jinja2.Jinja2 image.png
-
模板变量
image.png
image.png
在模版中使用:语法:{{变量名}}
1)命名由字母和数字以及下划线组成,不能有空格和标点符号。
2)不要和python或django关键字重名。原因:如果data是一个字典,那么访问data.items将会访问data这个字典的key名为items的值,而不会访问字典的items方法。 - 模板标签
标签语法:{% 标签名称 %}{% 结束标签名称 %}
例: {%tag%}{%endtag%}
if/elif/else:可以使用and/or/in/not/==/!=/<=/>=,来进行判断。ifequal/ifnotequal
#views.py
class Visit(View):
def get(self,request):
li = []
for i in range(1,10):
li.append(i)
#如果不想指定键值,可以使用locals(),locals()指获取当前能获取到的变量,形成一个字典
return render(request,'template_tag.html',locals())
#template_tag.html
<body>
{% for i in li %}
{% if i <= 5 %}
小:{{i}}
{% else %}
大:{{i}}
{% endif %}
{% if i == 5 %}
<br/>
{% endif %}
{% endfor %}
</body>
image.png
有时候可能在页面上要用上循环几次,可以用
{% for item in 'x'|ljust:'4' %} 循环四次
{%endfor %}
Django中{% ifequal A B %} 用来比较A和B两个值是否相等,{% ifnotequal A B %}` 用来比较A和B两个值是否不相等。
如:
{% ifequal price 0 %}
<span class="publicimg"><img src="/images/public.png"></span>
{% else %}
<span class="publicimg"><img src="/images/vip.png"></span>
{% endifequal %}
其中合法参数A,B只能是模板变量,字符串,整数和小数。
其他任何类型,例如Python的字典类型、列表类型、布尔类型,都不能作为合法参数用在 {% ifequal A B %} 中。
#forloop.counter:当前迭代的次数,下标从1开始。
#forloop.counter0:当前迭代的次数,下标从0开始。
#forloop.first:返回bool类型,如果是第一次迭代,返回true,否则返回false。
#forloop.last:返回bool类型,如果是最后一次迭代,返回True,否则返回False。
<body>
{% for i in li %}
{% if i <= 5 %}
小:{{i}}
{% else %}
大:{{i}}
{% endif %}
{% if i == 5 %}
<br/>
当前迭代次数,下标从1开始:{{forloop.counter}}
当前迭代次数,下标从0开始:{{forloop.counter0}}
<br/>
{% endif %}
{% if forloop.first %}
(这是第一次迭代)
{% elif forloop.last %}
(这是最后一次迭代)
{% endif %}
{% endfor %}
</body>
image.png
- 关于for ...empty...标签
<ul>
{% if athlete_list %}
{%手or、 athlete in athlete_list %}
<li>{{ athlete. name } }</li>
{% endfo「%}
{% else %}
<li>S o 「 ry, no athletes in this list.</li>
{% endif %}
</ul>
用 if来判断某个变量是否为空,如果不为空,就循环。因为这种判断在模板中经常会遇到 ,
所以 用ango 提供了 一种名为 for... empty 的标签,它的使用方法是 :
<u l>
{% fo「 ath lete i n athlete_list %}
<li>{{ athlete . name }}</li>
{% empty %}
<li> So「「y, no athletes in t his list.</li>
{% endfor %}
</ul>
- 过滤器
1)作用:对变量进行过滤。在真正渲染出来之前,过滤器会根据功能处理好变量,然后得出结果后再替换掉原来的变量展示出来。
2)语法:{{greeting|lower}}
,变量和过滤器中间使用管道符号”|”进行使用。
3)可以通过管道符号进行链式调用,比如实现一个功能,先把所有字符变成小写,把第一个字符转换成大写,如{{message|lower|capfirst}}
- 过滤器可以使用参数,在过滤器名称后面使用冒号”:”再加上参数,比如要把一个字符串中所有的空格去掉,则可以使用
cut
过滤器,代码如下{{message|cut:" "}}
,冒号和参数之间不能有任何空格,一定要紧挨着。 - R和time过滤器格式
获取当前时间
import datetime
nowTime = datetime.datetime.now()
#页面获取:
{{ nowTime|date:"Y-m-d H:i:s" }}
#views.py
# -*- coding: utf-8 -*-
from django.views import View
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.shortcuts import render,redirect
import datetime
class Visit(View):
def get(self,request):
#获取当前时间
nowTime = datetime.datetime.now()
message = '--Learn Python Language--'
#如果不想指定键值,可以使用locals(),locals()指获取当前能获取到的变量,形成一个字典
print(locals())
return render(request,'template_tag.html',locals())
#html文件
<body>
{{ message }}<br/>
upper过滤器大写:{{ message|upper }}<br/>
lower小写:{{ message|lower }}<br/>
cut去除‘--’:{{ message|cut:'--' }}<br/>
{{ nowTime }}<br/>
date过滤器:{{ nowTime|date:"Y-m-d H:i:s" }}<br/>
</body>
image.png
django常用过滤器
add
:字符串相加,数字相加,列表相加,如果失败,将会返回一个空字符串。
default
:提供一个默认值,在这个值被django认为是False的时候使用。比如:空字符串、None。区别于default_if_none,这个只有在变量为None的时候才使用默认值。
first
:返回列表中的第一个值。
last
:返回列表中的最后一个值。
date
:格式化日期和时间。
time
:格式化时间。
join
:跟python中的join一样的用法。
length
:返回字符串或者是数组的长度。
length_is
:字符串或者是数组的长度是否是指定的值。
lower
:把所有字符串都编程小写。
truncatechars
:根据后面给的参数,截断字符,如果超过了用…表示。
truncatewords
:同truncatechars,这个是以一个单词为单位进行截断。以上两个有xxx_html类型的,针对html,截断标签中的字符,而不会截断标签。
capfirst
:首字母大写。
slice
:切割列表。用法跟python中的切片操作是一样的,区间是前闭合后开放。
striptags
:去掉所有的html标签。
safe
:关闭变量的自动转义
floatformat
:浮点数格式化。
更多可以查询官方文档: https://yiyibooks.cn/xx/Django_1.11.6/ref/templates/builtins.html
英文:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/
date
时间过滤器格式
Y:四位数的年。如:1999
y:两位数的年。如:99
m:两位数的月。如:01,09
n:一位数的月。如:1,9,12
d:两位数的日。如:01,09,31
j:一位数的日。如:1,9,31
g:12小时制的一位数的小时。如:1,9,12
G:24小时制的一位数小时。如:0,8,23
h:12小时制的两位数的小时。如:01,09,12
H:24小时制的两位数的小时。如:01,13,24
i:分钟。从00-59
s:秒。从00-59
- 模板继承
1)模板继承使用extends标签实现。通过使用block来给子模板开放接口。
2)extends必须是模板中的第一个出现的标签。
3)子模板中的所有内容,必须出现在父模板定义好的block中,否则django将不会渲染。
4)如果出现重复代码,就应该考虑使用模板。尽可能多的定义block,方便子模板实现更细的需求。
模板继承允许你建立一个基本的”骨架”模板, 它包含你所有最常用的站点元素 并 定义了一些可以被子模板覆盖的block。
我们称它为 base.html, 定义了一些简单的 HTML 骨架文档, 你可以把它用到一些简单两列的网页上. “子” 模板的任务就是用内容填写这些空白的内容块.
block由子模板引用同名block块,来决定是否替换这些部分。block一般定义在base.html中 block是可以在那些继承base的html中添加内容的区。
子模板决定替换的block块,无须关注其它部分,没有定义的块即不替换,直接使用父模板的block块
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% block js %}
{% endblock js %}
</head>
<body>
{% block content %}
{% endblock content %}
</body>
</html>
login.html
{% extends "base.html" %}
{% block content %}
这是一个登录页面
{% endblock %}
include另一个模板
{% include "menu.html" %}
- 注释标签
- {#被注释的内容#}:将中间的内容注释掉。只能单行注释。
- {% comment %}被注释的内容{% endcomment %}:可以多行注释。
#基础模板
{% block title %}一些内容,这里可不填{% endblock %}
{% block content %}一些内容,这里可不填{% endblock %}
{% block footer %}一些内容,这里可不填{% endblock %}
#子模板的引用方式
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}<p>It is now {{ current_date }}.</p>{% endblock %}
extends ,必须为模板中的第一个模板标记 !
学以致用
- 使用render方法,渲染一个页面
- 页面中需要使用模版标签, 标签包括(if , else, for)
- 页面使用过滤器,包含upper, lower, date, cut
- 写一个登录页面,它继承一个模版
- 继承的模版需要include一个菜单栏页面
#base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title%}基本模板{% endblock %}</title>
<style>
*{
margin: 0;
padding: 0;
}
#topDiv,#bottomDiv{
background: black;
height: 40px;
width: 100%;
color: white;
text-align: center;
line-height: 40px;
}
#bottomDiv{
height: 90px;
line-height: 90px;
position: absolute;
bottom: 0;
}
{% block css%}
{% endblock %}
</style>
</head>
<body>
<div id="topDiv">
top顶部信息
</div>
<div id="bottomDiv">
bottom底部资料
</div>
{% block content %}
{% endblock %}
</body>
</html>
-------------------------------------------------------
#menu.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>菜单栏</title>
<style>
#menu{
width: 100%;
height: 60px;
color: #666;
}
#menu ul li{
list-style: none;
float: left;
margin: 20px;
}
</style>
<script src="jquery.js"></script>
</head>
<body>
<div id="menu">
<ul>
<li>首页</li>
<li>编程语言</li>
<li>项目实战</li>
<li>每日一学</li>
</ul>
</div>
</body>
</html>
----------------------------------------
#login.html
{% extends 'base.html' %}
{% block title %}login登录页面{% endblock %}
{% block css %}
#loginbox{
width: 400px;
height: 200px;
border: 1px solid red;
margin: 90px auto;
text-align: center;
}
{% endblock %}
{% block content%}
{% include 'menu.html' %}
<div id="loginbox">
<br/>
<h2>登录界面</h2>
<br/>
<form>
帐 号:<input type="text">
<br/>
<br/>
密 码:<input type="password">
<br/>
<br/>
<input type="submit" value="登录">
<input type="button" value="注册">
</form>
</div>
{% endblock content%}
#注意:如果是子页面,你的incude必须写在block内,因为子页面是获取不到block以为的内容,反正include可任意
在block以外写任何东西,前端都获取不到的,会被Django抛弃掉;
效果如下:
image.png