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:123{
%
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.