Django基础(二):templates

2017-10-17  本文已影响91人  宇辰星君

[TOC]

模板搜索机制

模板存放位置

但是,假如每个app的templates或者TEMPLATES定义路径中都有一个 index.html,
当在views.py中使用index.html模板时,直接写一个 render(request, 'index.html'),
或者当某个模板引用这个index.html模板时,直接写{% include/extends 'index.html' %},
Django 能不能找到想要的那个index.html呢?(答案是不一定能,有可能找错)

Django 模板查找机制:
Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。

所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,仅和该app相关的模板放在 app/templates/app/ 目录下面,这样,使用的时候,views templates引用模板就是"app1/index.html" 和 "app2/index.html" 这样有app作为名称的一部分,就不会混淆。

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',
            ],
        },
    },
]

如果需要,写足够多的 block 以便继承的模板可以重写该部分,include 是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便一些,在用到的地方include进去。其它的页面继承自 base.html 就好了,继承后的模板也可以在 block 块中 include 其它的模板文件。

demo

# suynblog/learn/views.py
def home(request):
    return render(request,'learn/home.html')
# suynblog/learn/urls.py
(r'^home/$',views.home,name='home'),

#suynblog/learn/templates/learn/base.html
<!DOCTYPE html>
<html>
<head>
    <title>
        {% block title %}NGS{% endblock %}
    </title>
</head>
<body>
{% include 'learn/nav.html' %}
{% block content %}
<div>这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。</div>
{% endblock %}
{% include 'learn/bottom.html' %}
{% include 'learn/tongji.html' %}
</body>
</html>

# suynblog/learn/templates/home.html
{% extends 'learn/base.html' %}
{% block title %}欢迎光临首页{% endblock %}
{% block content %}
这里是首页,欢迎光临!<br/>
{% include 'add.html' %}
{% endblock %}

变量

一般的变量之类的用 {{ }}(变量)
字符串、列表、字典

# views.py
def home(request):
    string = u"我在自强学堂学习Django,用它来建网站"
    TutorialList = ["HTML", "CSS", "jQuery", "Python", "Django"]
    info_dict = {'site': u'自强学堂', 'content': u'各种IT技术教程'}
    return render(request,'learn/home.html',
    {'string': string,'TutorialList': TutorialList,'info_dict': info_dict})

# home.html
{{ string }}
<br>
{% for i in TutorialList %}
{{ i }}
{% endfor %}
<br>
站点:{{ info_dict.site }} 内容:{{ info_dict.content }}<br>
{% for key, value in info_dict.items %}
    {{ key }}: {{ value }}
{% endfor %}

标签

功能类的,比如循环,条件判断是用 {% %}(标签)

1. if-elif-else-endif标签

模板中逻辑操作
==, !=, >=, <=, >, <,
and, or, not, in, not in

2. for-endfor标签

# views.py
List = map(str,range(100))  #int unicode str
# home.py
{% for item in List %}
    {{ item }}
    {% if not forloop.last %}
    ,
    {% endif %}
{% endfor %}

for循环中变量forloop有很多有用的属性:
forloop.counter 索引从 1 开始算
forloop.counter0 索引从 0 开始算
forloop.revcounter 索引从最大长度到 1
forloop.revcounter0 索引从最大长度到 0
forloop.first 当遍历的元素为第一项时为真
forloop.last 当遍历的元素为最后一项时为真
forloop.parentloop 用在嵌套的 for 循环中,获取上一层 for 循环的 forloop

当列表中可能为空值时用 for empty:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}
    <li>抱歉,列表为空</li>
{% endfor %}
</ul>

模板上得到对应视图网址:

# add.html
<a href="{% url 'learn:add3' a=4 b=5 %}">add3计算4+5</a><br/>

还可以使用 as 语句将内容取别名(相当于定义一个变量),多次使用(但视图名称到网址转换只进行了一次)

# add.html
{% url 'learn:add3' a=4 b=5 as add_url %}
<a href="{{ add_url }}">add3计算4+5</a><br/>

模板中获取当前网址,当前用户等:

如果在 views.py 中用的是render_to_response函数,不是render函数时,需要将 request 加入到上下文渲染器。

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',
            ],
        },
    },
]

根据'django.template.context_processors.request',在模板中我们就可以用request变量了。一般推荐用render而不是render_to_response。

{{ request.user }}
# 如果登陆就显示内容,不登陆就不显示内容:
{% if request.user.is_authenticated %}
    {{ request.user.username }},您好!
{% else %}
    请登陆,这里放登陆链接
{% endif %}
{{ request.path }}
{{ request.GET.urlencode }}
#判断 delete 参数是不是 1 来删除当前的页面内容
<a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">当前网址加参数 delete</a>

过滤器

上一篇下一篇

猜你喜欢

热点阅读