94django_template

94django_template

 

 

目录

template... 1

设置template引擎:... 1

设置公用templates和公用static... 2

view中使用template... 4

去掉urlstatic硬编码:... 5

获取和渲染模板:... 5

内置built-in template tagsfilters... 7

自定义template filter... 7

模板扩展extendsinclude包含:... 8

 

 

 

template

 

django内置了自己的模板引擎,和jinja很像,使用简单;

 

django默认会在app_name/templates/下寻找模板,在app_name/templates/下再建立app_name,这样app_name/templates/app_name/下存放与该app相关的模板,因为默认django会去所有的app下找模板,可能会优先找到其它app下的模板;

 

默认会到app_name/static/下寻找静态文件;

 

 

设置template引擎:

 

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        # 'BACKEND': 'django.template.backends.jinja2.Jinja2',

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

            ],

        },

    },

]

 

context_processors are functions that receive the current HttpRequest as an argument and return a dict of data to be added to the rendering context.

 

 

设置公用templates和公用static

mysite/mysite/settings.py

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR, 'templates')],

        'APP_DIRS': True,

……

STATIC_URL = '/static/'

STATICFILES_DIRS = [

    os.path.join(BASE_DIR, 'static'),

]

 

 

variables:

{{ var }}{{ dict.key }}{{ var.attr }}{{ var.method }}{{ var.index }}

 

模板引擎支持循环、判断、过滤器:

filter

{{ list|join:"," }}{{ name|lower }}

{{ now | date:"Y-m-d" }}

{{ name | length }}

 

tags

{% tag xxx %}{% endtag %}

{% for ... %}{% endfor %}

{# comment #}

 

for

{% for person in person_list %}

<li> {{ person.name }} </li>

{% endfor %}

 

if

{% if max > 10 %}

<li>max value is {{ max }} </li>

{% else %}

<li>max value is 10 </li>

{% endif %}

 

例:

>>> from django.template import Template,Context

>>> t = Template('My name is {{ name }}')

>>> c = Context({'name':'jowin'})   #context可以是 dict、属性、方法、tuple|list

>>> t.render(c)

'My name is jowin'

 

>>> t = Template('my name is {{ user.name }}')   #变量查找,dictattrmethodlisttuple

>>> class Person:

...     def __init__(self,name):

...             self.name = name

...

>>> user = Person('jowin')

>>> user.name

'jowin'

>>> c = Context({'user':user})

>>> t.render(c)

'my name is jowin'

 

>>> t = Template('my name is {{ user.name }}')

>>> class Person:

...     def name(self):

...             return 'jowin'

...

>>> user = Person()

>>> user.name()

'jowin'

>>> c = Context({'user':user})

>>> t.render(c)

'my name is jowin'

 

 

view中使用template

 

render源码,from django.shortcuts import render

def render(request, template_name, context=None, content_type=None, status=None, using=None):

    """

    Returns a HttpResponse whose content is filled with the result of calling

    django.template.loader.render_to_string() with the passed arguments.

    """

    content = loader.render_to_string(template_name, context, request, using=using)

    return HttpResponse(content, content_type, status)

 

另,render_to_response(),老版本1.6用;

 

 

mysite/polls/views.py

from django.http import HttpResponse

from .models import Question

from django.template import loader

 

# def index(request):

#     latest_question_list = Question.objects.order_by('-pub_date')[:4]

#     template = loader.get_template('polls/index.html')

#     context = {'latest_question_list': latest_question_list}

#     # output = ', '.join([q.question_text for q in latest_question_list])

#     return HttpResponse(template.render(context))   #1

def index(request):

    latest_question_list = Question.objects.order_by('-pub_date')[:4]

    context = {'latest_question_list': latest_question_list}

    return render(request, 'polls/index.html', context)   #2

 

mysite/polls/templates/polls/index.html

<img src="/static/django.png">   #mysite/polls/static/django.png

{% if latest_question_list %}

    <ul>

        {% for question in latest_question_list %}

        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

        {% endfor %}

    </ul>

{% endif %}

 

 

去掉urlstatic硬编码:

 

mysite/polls/templates/polls/index.html

{% load static %}

 

<img src="{% static 'django.png' %}">

{% if latest_question_list %}

    <ul>

        {% for question in latest_question_list %}

        <!--<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>-->

        <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

        {% endfor %}

    </ul>

{% endif %}

 

注:

{% url 'detail' question.id %}   #appurls.py中定义的name有关;app namespace改后,'detail'改为'polls:detail'

 

 

获取和渲染模板:

 

1

from django.template.loader import get_template

def get_template(template_name, using=None):   #返回一个模板对象,再使用模板对象的类方法Template中的render()渲染

    """

    Loads and returns a template for the given name.

    Raises TemplateDoesNotExist if no such template exists.

    """

    chain = []

    engines = _engine_list(using)

    for engine in engines:

        try:

            return engine.get_template(template_name)

        except TemplateDoesNotExist as e:

            chain.append(e)

 

    raise TemplateDoesNotExist(template_name, chain=chain)

 

class Template(object):

    def __init__(self, template_string, origin=None, name=None, engine=None):

                   ……

    def _render(self, context):

        return self.nodelist.render(context)

 

    def render(self, context):

        "Display stage -- can be called many times"

        with context.render_context.push_state(self):

            if context.template is None:

                with context.bind_template(self):

                    context.template_name = self.name

                    return self._render(context)

            else:

                return self._render(context)

 

 

2

from django.shortcuts import render

def render(request, template_name, context=None, content_type=None, status=None, using=None):

    """

    Returns a HttpResponse whose content is filled with the result of calling

    django.template.loader.render_to_string() with the passed arguments.

    """

    content = loader.render_to_string(template_name, context, request, using=using)

    return HttpResponse(content, content_type, status)

 

 

3

from django.template.loader import render_to_string

def render_to_string(template_name, context=None, request=None, using=None):

    """

    Loads a template and renders it with a context. Returns a string.

 

    template_name may be a string or a list of strings.

    """

    if isinstance(template_name, (list, tuple)):

        template = select_template(template_name, using=using)

    else:

        template = get_template(template_name, using=using)

    return template.render(context, request)

 

 

内置built-in template tagsfilters

 

block   #Defines a block that can be overridden by child templates.{% block custom_title %}首页{% endblock %}

csrf_token   #htmlform标签中使用,{% csrf_tokne %}

extends   #模板扩展,{% extends 'base.html' %}

include   #模板包含,{% include 'pagination.html' %}

url   # <h4><a href="{% url 'article_detail' article.id %}">{{ article.title }}</a></h4>

filter

for

for ... empty

if

 

例:

{% for ad in ads %}

<a href="{{ ad.callback_url }}" target="_blank">

    <img id="slide-img-{{ forloop.counter }}" src="{{ MEDIA_URL }}{{ ad.image_url }}" alt="" />

</a>

{% endfor %}

 

 

过滤器使用格式:

{{ 变量|过滤器:参数 }}

add   # <div class="module1_{{ forloop.counter|add:2 }} box">

center

date   # <div>{{ article.date_publish|date:'d' }}</div>{{ article.date_publish|date:'Y-m-d' }}

default

dictsort

dictsortreversed

filesizeformat

length

last

ljust

lower

random

rjust

safe   # 告诉browser,这个变量是安全的,可以渲染,没必要显示纯文本,{{ article.content | safe }}

title

truncatewords   #如果后端传的数据太多,只显示一部分,{{ value|truncatewords:3 }},截取3个单词

 

 

i18n

tz

 

static   #{% load static %}{% load staticfiles %}

get_static_prefix   # <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!">

get_media_prefix

 

例:

{% extends "base.html" %}

{% block content %}

         <h3>Publishers</h3>

         <ul>

                   {% for publisher in object_list %}

                   <li>{{ publisher.name }}</li>

                   {% endfor %}

         </ul>

{% endblock %}

 

{% ifequal a b %} ... {% endifequal %} is an obsolete way to write {% if a == b %} ... {% endif %}

Likewise,

{% ifnotequal a b %} ... {% endifnotequal %} is superseded by {% if a != b %} ... {% endif %}

The ifequal and ifnotequal tags will be deprecated in a future release.

 

{% for current_org in hot_orgs %}

    <dl>

        <dt class="num fl">{{ forloop.counter }}</dt>   #The current iteration of the loop (1-indexed)

        <dd>

            <a href="/company/2/"><h2>{{ current_org }}</h2></a>

            <p>{{ current_org.address }}</p>

        </dd>

    </dl>

{% endfor%}

 

自定义template filter

 

django寻找自定义filter的目录是app_name/templatetags/

 

例:

mysite/polls/templatetags/mytags.py

from django import template

 

register = template.Library()

 

@register.filter

def lower(text):

    return text.lower()

 

@register.filter

def question_choice_count(question):

    return question.choice_set.count()

 

@register.filter

def question_choice_count_add(question, num):

    return question.choice_set.count() + int(num)

 

mysite/polls/templates/polls/index.html

{% load static %}

{% load mytags %}

 

<img src="{% static 'django.png' %}">

{% if latest_question_list %}

    <ul>

        {% for question in latest_question_list %}

        <!--<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>-->

        <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a>

        -- {{ question|question_choice_count }}</li>

        {% endfor %}

    </ul>

{% endif %}

 

 

模板扩展extendsinclude包含:

 

实现网页布局;

 

extends是继承模板,然后自定义可设置的block

include是导入一个模板片段到该位置;