05 Django template layer

You may have noticed that we return the text in the example view the way a bit special. In other words, HTML is hard-coded directly in the Python code.

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

Although this technique is easy to explain how the work of view, but directly to the hard-coded into your HTML view actually not a good idea. Let's look at why:

  • Any changes to the page design must make the appropriate changes to the Python code. Site design modifications are often much more frequently than change the underlying Python code, so if the design can be changed without modify the Python code, it will be much more convenient.

  • Python code written in HTML and design are two different jobs, and most professional Web development environments will assign them to different people (and even different departments) to complete. Designers and HTML / CSS coders should not be asked to edit Python code to get their job done.

  • Writing Python code and designers making templates two programmers work simultaneously efficiency is the highest, far better than to let a person waiting for the other to finish editing work on a file that contains both Python and HTML are included.

For these reasons, the design of the page and code separation Python's much cleaner and easier to maintain. We can use Django's  template system  (Template System) to implement this model, which is the problem to be discussed in detail in this chapter.

1
python的模板:HTML代码+模板语法
DEF CURRENT_TIME (REQ):
     # ================================ original view function 
    # Import datetime 
    # now datetime = .datetime.now () 
    # HTML = "<HTML> <body> current time: <h1 of>% S </ h1 of> </ body> </ HTML>."% now 

    # ========= ======================= django template modifications view function 
    # from the django.template Import template, the Context 
    # now datetime.datetime.now = () 
    # T = Template ( '<html> < body> is the current time: <h1 of> CURRENT_DATE {{}} </ h1 of> </ body> </ HTML>') 
    # # to get_template T = ( 'the current_datetime.html') 
    # C the Context = ({ 'CURRENT_DATE': STR (now)}) 
    # HTML = T.render(c)
    #
    # return HttpResponse(html)

    #另一种写法(推荐)
    import datetime
    now=datetime.datetime.now()
    return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})

 

1 template syntax of variables

Key traversing complex data structures in Django templates is the dot character, the syntax:  

1
{{var_name}}

views.py:

def index(request):
    import datetime
    s="hello"
    l=[111,222,333]    # 列表
    dic={"name":"yuan","age":18}  # 字典
    date = datetime.date(1993, 5, 2)   # 日期对象

    class Person(object):
        def __init__(self,name):
            self.name=name
 
    person_yuan=Person("yuan")  # 自定义类对象
    person_egon=Person("egon")
    person_alex=Person("alex")
 
    person_list=[person_yuan,person_egon,person_alex]
 
    return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})

 

template: 

1
2
3
4
5
6
<h4>{{s}}< / h4>
<h4>列表:{{ l. 0  }}< / h4>
<h4>列表:{{ l. 2  }}< / h4>
<h4>字典:{{ dic.name }}< / h4>
<h4>日期:{{ date.year }}< / h4>
<h4>类对象列表:{{ person_list. 0.name  }}< / h4>

NOTE: symbol period method (method without parameters) of the referenced object can also be used:

1
<h4>字典:{{ dic.name.upper }}< / h4>

2 of the filter template

grammar:

1
{{obj|filter__name:param}}

default

If a variable is false or empty, the default values ​​given. Otherwise, use the value of the variable. E.g:

1
{{ value|default: "nothing"  }}

length

That returns a value. It works both strings and lists. E.g:

1
{{ value|length }}

If the value is [ 'a', 'b', 'c', 'd'], the output is 4.

filesizeformat

Value formatted as a "human readable" file size (e.g.  '13 KB''4.1 MB''102 bytes', etc.). E.g:

1
{{ value|filesizeformat }}

If  value is 123456789, the output will be  117.7 MB.  

date

如果 value=datetime.datetime.now()

1
{{ value|date: "Y-m-d"  }}  

slice

If the value = "hello world"

1
{{ value| slice : "2:-1"  }}

truncatechars

If the string of characters is more than a specified number of characters, it will be truncated. Translatable strings will be truncated sequence at the end of the ellipsis ( "...").

Parameters: the number of characters to be truncated

E.g:

1
{{ value|truncatechars: 9  }}

safe

JS and HTML tags will be syntactic tags Django template automatically escapes, for obvious reasons, this is for safety. But sometimes we might not want these HTML elements are escaped, for example, we do a content management system, add background of the article is modified, these modifications may be raised by a similar FCKeditor editing the HTML modifier text, escaped, then automatically displayed if the source file is to protect HTML tags. To turn off the automatic Django escaped HTML in two ways, if it is a single variable we can filter | tell Django "safe" way to secure this code is not necessary to escape. such as:

1
value = "<a href=" ">点击</a>"
1
{{ value|safe}}

Here are some simple common filter templates, more detailed

3 of label template 

Tag looks like this:  {% tag %}. Tag is more complex than a variable: some additional information creating in the output text, a number or to control flow through the logic loop, some variables will be used to load subsequent to the template. Some tags require the start and end tags (e.g., {% tag %} ...tag content ... {% endtag%}).

for labels

Through each element:

{% for person in person_list %}
    <p>{{ person.name }}</p>
{% endfor %}

You may be utilized {%  for  obj  in  List  the reversed  %} reverse completing the cycle.

Traversing a dictionary:

{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

NOTE: cycle number can be displayed {{forloop}} 

forloop.counter            The current iteration of the loop (1-indexed)
forloop.counter0           The current iteration of the loop (0-indexed)
forloop.revcounter         The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0        The number of iterations from the end of the loop (0-indexed)
forloop.first              True if this is the first time through the loop
forloop.last               True if this is the last time through the loop

 

for ... empty

for  label with an optional {%  empty  %}  clause set forth in order to empty or is not found, the operation may be.

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

if the label

% {  IF  %} be a variable evaluation, if its value is "True" (exists, it is not empty, and not false boolean value type), the block will output the corresponding content.

{% IF NUM> 100 or NUM <0% }
     <P> Invalid </ P> 
{ % elif NUM> 80 and NUM <100% }
     <P> Elite </ P> 
{ % the else % }
     <P> Minato live it </ P> 
{ %} endif%

with

Use a simple name cache a complex variable , when you need to use an "expensive" method (such as database access) many times when it is very useful

E.g:

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

csrf_token

This tag for protection CSRF

4 custom tags and filters

1, INSTALLED_APPS in the current configuration settings in the app, django otherwise unable to find simple_tag custom.

2. Create a module in the app templatetags in (name of the module can only be templatetags )

3, create any .py files, such as: my_tags.py

from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()   #register的名字是固定的,不可改变
 
@register.filter
def filter_multi(v1,v2):
    return  v1 * v2
<br>
@register.simple_tag
def simple_tag_multi(v1,v2):
    return  v1 * v2
<br>
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

 

4, before using import custom filter simple_tag and html files created my_tags.py

1
{ %  load my_tags  % } 

5, using simple_tag and filter (how to call)

1
2
3
4
5
6
7
8
9
10
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .html
{ %  load xxx  % }  
      
# num=12
{{ num|filter_multi: 2  }}  #24
 
{{ num|filter_multi: "[22,333,4444]"  }}
 
{ %  simple_tag_multi  2  5  % }  参数不限,但不能放在 if  for 语句中
{ %  simple_tag_multi num  5  % }

Note: filter can be used in the if statements, simple_tag not

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

 

5 template inheritance (extend)

Django template engine is the most powerful and most complex part of the template is inherited. Template inheritance allows you to create a basic "skeleton" template that contains all the elements of your site, and you can define templates quilt blocks can covered.

By starting from the following example, it is easy to understand template inheritance:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

This template, we call it  base.html, it defines a simple HTML skeleton can be used in a two page layout. "Sub template" work with their contents fill the empty blocks.

In this example,  block the tag may define three content-filled quilt template block. block Tell template engine: child template may override the templates in these locations.

Child template might look like this:

{% extends "base.html" %}
 
{% block title %}My amazing blog{% endblock %}
 
{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

extends Tag is the key here. It tells the template engine that this template "inherited" another template. When the system processes the stencil template, firstly, it will locate the parent template - in this case, is "base.html".

At that time, the template engine will notice  base.html the three  block labels, and with the contents of the sub-template to replace the block. The  blog_entries value of the output may look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>My amazing blog</title>
</head>
 
<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>
 
    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>
 
        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

Please note that the child template does not define the  sidebar block, so the system uses the value of the parent template. Parent template  {% block %} Content tab is always used as an alternative content (fallback).

This provides the greatest degree of code reuse, and that add content to the shared content area more simple, e.g., in the range of the navigation portion.

Here are some tips for using inheritance:

  • If you use the template  {% extends %} label, it must be the first template tag. Under any other circumstances, template inheritance will not work.

  • Set in the more base templates  {% block %} , the better label. Remember, child templates do not have to define all parent blocks of templates, so you can fill in most reasonable default content blocks, and then, only the definition that the one you need. Hook a little bit more is better than less good.

  • If you find yourself duplicating content in a large number of templates, it probably means you should move the contents to the parent of a template  {% block %} in.

  • If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.

  • For better readability, you can also give your  {% endblock %} tag a  name  . E.g:

    1
    2
    3
    { %  block content  % }
    ...
    { %  endblock content  % }  

    In large template, this method to help you clearly see what a   {% block %} label is closed.

  • A plurality of the same name can not be defined in a template  block tag.

 

Guess you like

Origin www.cnblogs.com/bilx/p/11781237.html