美文网首页
Django基础(二):templates

Django基础(二):templates

作者: 宇辰星君 | 来源:发表于2017-10-17 21:42 被阅读91次

    [TOC]

    模板搜索机制

    模板存放位置

    • 每个app的templates文件夹
    • settings.py参数TEMPLATES/DIRS设置路径
      Django会自动去这两类文件夹中寻找模板。

    但是,假如每个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 %}
    
    • 获取当前网址及GET参数
    {{ request.path }}
    {{ request.GET.urlencode }}
    #判断 delete 参数是不是 1 来删除当前的页面内容
    <a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">当前网址加参数 delete</a>
    

    过滤器

    相关文章

      网友评论

          本文标题:Django基础(二):templates

          本文链接:https://www.haomeiwen.com/subject/oryjuxtx.html