我的dajngo2.0学习笔记
Django模板
渲染模板
渲染模板有两种方式。这里讲下两种常用的方式。
1. render_to_string
找到模板,然后将模板编译渲染成Python的字符串格式。最后再通过HttpResponse对象返回回去。实例代码如下:
from djiango.temple.loader import render_to_string
from djiango.http import HttpResponse
def book_detail(request,book_id):
html = render_to_string("detail.html")
return HttpResponse(html)
2.HttpResponse
以上方式虽然已经很方便,但是django还提供了一个更加简便的方式,直接将模板渲染成字符串和包装成 HttpResponse 对象一步到位完成,实例代码如下:
from django.shortcuts import render
def book_list(request):
return render(request,'list.html')
模板查找路径:
在项目的settings.py文件中,有一个TEMPLATES的配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等,模板路径可以在两个地方配置。
1. DIRS
:
这是一个列表,在这个列表中存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板的时候,会在这个列表的路径中查找模板。
2. APP_DIRS
:
默认为 True ,这个设置为 True后,会在INSTALLED_APPS的安装了的APP下的templates文件加中查找模板。
3. 查找顺序:
比如代码render(‘list.html’)。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中的所有路径都没有找到,那么会先检查当前这个视图所处的APP是否已经安装,如果安装了就先在当前这个APP下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径都没有找到,就会抛出一个TemplateDoesNotExist的异常。
模板变量
-
在模板中使用变量,需要将变量放到
{{变量}}
中. -
如果想要访问对象的属性,那么可以通过
对象.属性名
来进行访问。
class Person(object):
def __init__(self,username):
self.username = username
context = {
'person': p
}
以后想要访问person
的username
,那么就是通过person.username
来访问.
- 如果想要访问一个字典的key对应的value,那么只能通过
字典.key
的形式进行访问,不能通过[]
的形式进行访问。
context = {
'person':{
'username': 'wjx'
}
}
- 因为在访问字典的
key
时候也是使用.
来访问,因此不能在字典中定义字典本身就有的属性名当作key
,否则字典的哪个属性将变成字典中的key了
context = {
'person':{
'username': 'wjx'
'keys': 'abc'
}
}
以上因为将key
作为pereson
这个字典的key
了。因此以后在模板中访问person.keys
的时候,返回的不是这个字典的所有key,而是对应的值。
- 如果想要访问列表或者元组,那么也是通过
.
的方式进行访问,不能通过[]
的形式进行访问。这一点和python中是不一样的。实例代码如下:
{{ persons }}
常用模板标签
1. if标签
1.所有的标签都是在{% %}
之间
2.if标签有闭合标签。就是{% endif %}
3.if标签的判断运算符,就跟python中的判断运算符是一样的。
4.还可以使用elif
以及else
等标签。
注:新建templates文件夹后,出现TemplateDoesNotExist at / index.html
错误,
可以尝试在setting文件中的 TEMPLATES 栏的里面的‘DIRS’ = [] 括号里面加上:
os.path.join(BASE_DIR, 'templates')
2. for…in…标签:
for...in...
类似于python中的for...in...
。可以遍历列表、元组、字符串、字典等一切可遍历的对象。实例代码如下:
<!-- <ul>
{% for book in books %}
<li> {{ book }} </li>
{% endfor %}
</ul> -->
如果想要反向遍历,那么在遍历的时候就加上一个reversed
。实例代码如下:
<!-- <ul>
{% for book in books reversed %}
<li> {{ book }} </li>
{% endfor %}
</ul> -->
遍历字典的时候,需要使用item
、keys
和value
等方法。在DTL
中,执行一个方法不能使用圆括号的形式。遍历字典实例代码如下:
{% for key,value in person.items %}
<p> key: {{ key }} </p>
<p> value: {{ value }} </p>
{% endfor %}
在for
循环中,DTL
提供了一些变量可供使用。这些变量如下:
forloop.counter
:当前循环的下标,以1作为起始值
forloop.counter0
:当前循环的下标,以1作为起始值
forloop.revcounter
:反向遍历
forloop.revcounter0
:反向遍历,以1作为起始值
forloop.first
:是否是第一次遍历
forloop.last
:是否是最后一次遍历
forloop.parentloop
:代表上一级的for循环
3. for...in...empty
标签
在遍历的对象如果没有元素的情况下,会执行empty
中的内容。实例代码如下:
{% for comment in comments %}
<li> {{ comment }} </li>
{% empty %}
<li>没有任何评论</li>
{% endfor %}
4. url标签
在模板中,我们经常需要写一些url
,比如某个a
标签中需要定义href
属性。当然如果通过硬编码的方式直接将这个url
写死在里面也是可以的。但是这样对于以后项目维护不是一件好事。因此建议使用这种反转的方式来实现,类似于django
中的reverse
一样。实例代码如下:
<a href="{% url 'book:list' %}">图书列表页面</a>
如果url
反转的时候需要传递参数,那么可以在后面传递。但是参数分位置参数和关键字参数。位置参数和关键字参数不能同时使用。实例代码如下:
#path部分
path('book/detail/<book_id>/',views.book_detail,name='detail')
#url反转,使用位置参数
<a href="{% url 'book_detail' 1 %}">图书详情页面</a>
#url反转,使用关键字参数
<a href="{% url 'book_detail' book_id=1 %}">图书详情页面</a>
如果想要在使用url
标签反转的时候要传递查询字符串的参数,那么必须要动手再在后面添加。实例代码如下:
<a href="{% url 'book_detail' book_id=1 page=2 %}">图书详情页面</a>
模板常用过滤器:
"date"过滤器
#view.py
context ={
"birthady": datetime.now()
}
date.html
{{ birthady|date:"Y/m/d" }}
那么将会输出’2019/08/24’。其中Y
代表的是四位数字的年份,m
代表的是两位数字的月份,d
代表的是两位数字的日。
|格式字符| |描述| |示例|
=====================================
|Y| 四位数字的年份 | 2018 |
|m| 两位数字的月份 | 01-12 |
|n| 月份,无0前缀 | 1-12 |
|d| 两位数字的天 | 01-31 |
|j| 天,无0前缀 | 1-31 |
|g| 小时,12小时格式,无0前缀 | 1-12 |
|h| 小时,12小时格式。 | 01-12 |
|G| 小时,24小时格式,无0前缀 | 0-23 |
|H| 小时,24小时格式。 | 00-23 |
|i| 分钟。 | 00-59 |
|s| 秒钟。 | 00-59 |
=====================================
模板继承:
在前端页面开发中,有一些代码是可以重复使用的。这种情况可以使用include
标签来实现。也可以使用另外一个比较强大的方式来实现,那就是模板继承。模板继承类似于Python
中的类,在父类中可以定义好一些变量和方法,然后在子类中实现。模板继承也可以在父模板中先定义好一些变量和方法,然后在子类中实现。因为子模板有自己不同的代码,因此可以在父模板中定义一个block接口,然后子模版再去实现。以下是父模板的代码:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<header>
<ul>
<li><a href="/">首页</a></li>
<li><a href="{% url 'company' %}">公司</a></li>
<li><a href="{% url 'school' %}">校园</a></li>
<li>{{ username }}</li>
</ul>
</header>
<div class="content">
{% block content %}
这是父模板代码
{% endblock %}
</div>
<footer>
这是footer部分
</footer>
</body>
</html>
这个模板叫做base.html
,定义好一个简单的html
骨架,然后定义好两个block
接口,让子模版来根据具体需求实现。子模版然后通过extends
标签来实现,实例代码如下:
{% extends 'base.html'%}
{% block content %}博客列表{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}