elements using the Div objects. This is useful when specific JavaScript needs to be applied to some form fields.
688 |
689 | 除了普通的字段,当这些字段使用help块实现之后,你可以传递HTML片段图片字段。你也可以在布局中应用预先准备的文本字段。例如,我们对Phone字段添加一个电话图标,对Email字段添加一个@符号。你可以从contact字段例子总看到,我们很容易地在
元素中死哦难过Div对象包裹字段。这在需要某些表单字段指定JavaScript时非常有用。
690 |
691 | The action attribute for the HTML form is defined by the form_action property of the form helper. If you use the empty string as an action, the form will be submitted to the same view, where the form is included. The method attribute of the HTML form is defined by the form_method property of the form helper. As you know, the HTML forms allow the GET and POST methods. Finally, there is a Submit object in order to render the submit button, which takes the name of the button as the first positional argument and the value of the button as the second argument.
692 |
693 | HTML表单的action属性是由表单辅助器的属性form_action的。如果你使用空字符串作为action,表单会被提交到相同的包含了这个表单的视图。HTML表单的方法method属性是由表单辅助器的form_method属性定义的。你也知道的,HTML表单允许GET和POST方法。最后,是渲染提交按钮的Submit对象,它接受按钮的名字作为第一个位置参数,按钮的值作为第二个参数。
694 |
695 | ### There's more… 更多相关内容
696 |
697 | For the basic usage, the given example is more than necessary. However, if you need a specific markup for the forms in your project, you can still overwrite and modify templates of the django-crispy-forms app as there is no markup hardcoded in the Python files, rather all the generated markup is rendered through the templates. Just copy the templates from the django-crispy-forms app to your project's template directory and change them as required.
698 |
699 | 对基本的用法来说,给出的例子非常有必要。不过,如果你需要为项目中的表单指定装饰,你仍旧可以重写或者修改django-crispy-forms应用的模板,
700 |
701 | ### See also 参见
702 |
703 | - The Filtering object lists recipe
704 | - The Managing paginated lists recipe
705 | - The Downloading authorized files recipe
706 |
707 | - 过滤对象列表技法
708 | - 管理分页列表技法
709 | - 下载授权文件技法
710 |
--------------------------------------------------------------------------------
/第二版/第五章-自定义模板过滤器和标签.md:
--------------------------------------------------------------------------------
1 | # Chapter 5. Custom Template Filters and Tags
2 |
3 | In this chapter, we will cover the following topics:
4 |
5 | Following conventions for your own template filters and tags
6 | Creating a template filter to show how many days have passed since a post was published
7 | Creating a template filter to extract the first media object
8 | Creating a template filter to humanize URLs
9 | Creating a template tag to include a template if it exists
10 | Creating a template tag to load a QuerySet in a template
11 | Creating a template tag to parse content as a template
12 | Creating a template tag to modify request query parameters
13 |
14 | ## Introduction
15 |
16 | As you know, Django has an extensive template system with features such as template inheritance, filters to change the representation of values, and tags for presentational logic. Moreover, Django allows you to add your own template filters and tags to your apps. Custom filters or tags should be located in a template-tag library file under the templatetags Python package in your app. Then, your template-tag library can be loaded in any template with a {% load %} template tag. In this chapter, we will create several useful filters and tags that will give more control to template editors.
17 |
18 | To see the template tags of this chapter in action, create a virtual environment, extract the code provided for this chapter there, run the development server, and visit http://127.0.0.1:8000/en/ in a browser.
19 |
20 | ## Following conventions for your own template filters and tags
21 |
22 | Custom template filters and tags can become a total mess if you don't have persistent guidelines to follow. Template filters and tags should serve template editors as much as possible. They should be both handy and flexible. In this recipe, we will take a look at some conventions that should be used when enhancing the functionality of the Django template system.
23 |
24 | ### How to do it...
25 |
26 | Follow these conventions when extending the Django template system:
27 |
28 | 1. Don't create or use custom template filters or tags when the logic for the page fits better in the view, context processors, or model methods. When your content is context-specific, such as a list of objects or object-detail view, load the object in the view. If you need to show some content on every page, create a context processor. Use custom methods of the model instead of template filters when you need to get some properties of an object that are not related to the context of the template.
29 | 2. Name the template-tag library with the _tags suffix. When your app is named differently than your template-tag library, you can avoid ambiguous package importing problems.
30 |
31 | 3. In the newly created library, separate the filters from tags, for example, using comments as shown the following code:
32 |
33 | ```python
34 | # utils/templatetags/utility_tags.py
35 | # -*- coding: UTF-8 -*-
36 | from __future__ import unicode_literals
37 | from django import template
38 | register = template.Library()
39 |
40 | ### FILTERS ###
41 | # .. your filters go here..
42 |
43 | ### TAGS ###
44 | # .. your tags go here..
45 | ```
46 |
47 | 4. When creating advanced custom template tags, make sure that their syntax is easy to remember by including the following constructs:
48 |
49 | - for [app_name.model_name]: Include this construct in order to use a specific model
50 | - using [template_name]: Include this construct in order to use a template for the output of the template tag
51 | - limit [count]: Include this construct in order to limit the results to a specific amount
52 | - as [context_variable]: Include this construct in order to save the results to a context variable that can be reused multiple times
53 |
54 | 5. Try to avoid multiple values that are defined positionally in the template tags, unless they are self-explanatory. Otherwise, this will likely confuse the template developers.
55 | 6. Make as many resolvable arguments as possible. Strings without quotes should be treated as context variables that need to be resolved or short words that remind you of the structure of the template tag components.
56 |
57 | ## Creating a template filter to show how many days have passed since a post was published
58 |
59 | Not all people keep track of the date and when talking about creation or modification dates of cutting-edge information; for many of us, it is convenient to read the time difference. For example, the blog entry was posted three days ago, the news article was published today, and the user last logged in yesterday. In this recipe, we will create a template filter named days_since, which converts dates to humanized time differences.
60 |
61 | ### Getting ready
62 |
63 | Create the utils app and put it under INSTALLED_APPS in the settings, if you haven't done that yet. Then, create a templatetags Python package in this app (Python packages are directories with an empty `__init__.py` file).
64 |
65 | ### How to do it...
66 |
67 | Create a utility_tags.py file with the following content:
68 |
69 | ```python
70 | # utils/templatetags/utility_tags.py
71 | # -*- coding: UTF-8 -*-
72 | from __future__ import unicode_literals
73 | from datetime import datetime
74 | from django import template
75 | from django.utils.translation import ugettext_lazy as _
76 | from django.utils.timezone import now as tz_now
77 | register = template.Library()
78 |
79 | ### FILTERS ###
80 |
81 | @register.filter
82 | def days_since(value):
83 | """ Returns number of days between today and value."""
84 |
85 | today = tz_now().date()
86 | if isinstance(value, datetime.datetime):
87 | value = value.date()
88 | diff = today - value
89 | if diff.days > 1:
90 | return _("%s days ago") % diff.days
91 | elif diff.days == 1:
92 | return _("yesterday")
93 | elif diff.days == 0:
94 | return _("today")
95 | else:
96 | # Date is in the future; return formatted date.
97 | return value.strftime("%B %d, %Y")
98 | ```
99 |
100 | ### How it works...
101 |
102 | If you use this filter in a template as shown in the following code, it will render something similar to yesterday or 5 days ago:
103 |
104 | ```python
105 | {% load utility_tags %}
106 | {{ object.published|days_since }}
107 | ```
108 |
109 | You can apply this filter to values of the date and datetime types.
110 |
111 | Each template-tag library has a register, where filters and tags are collected. Django filters are functions registered by the @register.filter decorator. By default, the filter in the template system will be named same as the function or other callable object. If you want, you can set a different name for the filter by passing the name to the decorator, as follows:
112 |
113 | ```python
114 | @register.filter(name="humanized_days_since")
115 | def days_since(value):
116 | ...
117 | ```
118 |
119 | The filter itself is quite self-explanatory. At first, the current date is read. If the given value of the filter is of the datetime type, date is extracted. Then, the difference between today and the extracted value is calculated. Depending on the number of days, different string results are returned.
120 |
121 | ### There's more...
122 |
123 | This filter is also easy to extend in order to show the difference in time, such as just now, 7 minutes ago, and 3 hours ago. Just operate on the datetime values instead of the date values.
124 |
125 | ### See also
126 |
127 | - The Creating a template filter to extract the first media object recipe
128 | - The Creating a template filter to humanize URLs recipe
129 |
130 | ## Creating a template filter to extract the first media object
131 |
132 | Imagine that you are developing a blog overview page, and for each post, you want to show images, music, or videos in that page taken from the content. In such a case, you need to extract the
,
,