Django custom tags and filters

Source: Internet
Author: User
Django custom tags and filters

 

Django supports custom tags and filters. At first, I did not pay much attention to this feature, but recently I tried to customize tags. It's really nice to find Django.

 

Create a Python source folder in an app of your project __. py .) the folder name is templatetags. this folder stores the source code of custom tags and filters.

 

If the tag is defined in the templatetags folder, such as test_tags.py, how can we use our custom test_tags.py. Simply add {% load test_tags %} to the Django template and use the custom tag in the test_tags.py source file in the load statement template.

 

The following describes in detail how to create a custom tag.

 

1. Create a project without saying anything about the app. Just create the templatetags folder mentioned above in a random app.

This is a bit hard to understand. Can I use a tags app created in any app? At first, I was confused about this. Assume that the tags created under an app can be used by this app. In order for everyone to use their own defined tags, I also want to take out templatetags separately, which is in a similar position as a normal app in the project. This idea has been developed for a long time and cannot be found. Instead, we had to use copy to copy templatetags in every app. (Of course, this is just my original incorrect idea) but later I found that, in an app, other apps can directly use this custom file. You only need to call the load statement in the required template (no matter the template is in your app) to load the custom file.

Then I looked at some documents. As long as the location of templatetags is configured in installed_apps in settings. py, or configured in template_dirs, any location can be used.

Remember to include the _ init _. py file in the templatetags folder. Empty file.

 

2. Compile the custom file code test_tags.py.

 

Now let's look at the simple filter ).

A simple code of mine is as follows:

Python code
  1. #! /Usr/bin/ENV Python
  2. # Coding: UTF-8
  3. From Django import Template
  4. Register = template. Library ()
  5. Def percent_decimal (value ):
  6. Value = float (STR (value ))
  7. Value = round (value, 3)
  8. Values = value * 100
  9. Return STR (value) + '%'
  10. Register. Filter ('percent _ decimal ', percent_decimal)

The code above means to convert the passed decimal points into percentages. (Django's built-in widthratio tab can solve this problem, but its error is too large, and the decimal point is cut off directly ).

Here, the register = template. Library (), register. Filter ('percent _ decimal ', percent_decimal) statements are used to register the written code with usable labels. Register. Filter ('percent _ decimal ', percent_decimal) in the last sentence ). The first parameter is a string, and the name can be obtained only when it is used in the template, for example, {12.09 | percent_decimal. The following parameter accepts a function name, which is the custom percent_decimal method above. The value parameter in this method is passed from the template. For example, {12.09 | percent_decimal}, the value parameter accepted by the percent_decimal method is
12.09.

 

Let's take a look at how to customize tags.

Custom tags is a little more complex than custom filters. However, it is not difficult to study it carefully.

The basic format of custom tags is as follows:

Python code
  1. From Django import Template
  2. Register = template. Library ()
  3. Class testnode (template. node ):
  4. Def _ init _ (Self ):
  5. Pass
  6. Def render (self, context ):
  7. Return "XXXXX"
  8. Def test (parser, token ):
  9. Return testnode ()
  10. Register. Tag ('My _ tag', test)

The package introduction and registration and the filter type. The main function code is a class (inherited from template. node, all custom tags must be inherited from this class) and a method. The above Code does not provide any function, but we must first understand its implementation mechanism.

If the preceding custom tags are used in the template, for example, {% my_tag AAA. bbb %}, the test method registered in the code above will be called. The test method has two parameters, one of which is parser. This function is quite big and will be explained later. The other is token, which is all strings contained in the tag used in the template. If {my_tag AAA. BBB} is used, the token value is "my_tag AAA. BBB ". Note that it is a string type.

Next, call the testnode class, and there is a render method. One of the parameters is context. This context parameter is passed in by view during template rendering, the same variables can be called in the rendered template. You can print "Print user" in render to display the login user information.

 

After understanding the implementation mechanism of custom tags. Look at a little complicated code.

Python code
  1. Class permissionlevel (template. node ):
  2. """
  3. Return the corresponding value based on the level
  4. """
  5. Def _ init _ (self, sequence, text_level ):
  6. Self. Sequence = Sequence
  7. Self. text_level = text_level
  8. Pass
  9. Def render (self, context ):
  10. Userinfo = context ['user']
  11. Level = 4 # obtain the user level
  12. Values = self. sequence. Resolve (context, true)
  13. If self. text_level <= level:
  14. Return STR (values)
  15. Else:
  16. Return 'xxx'
  17. Def do_permission_level (parser, token ):
  18. Try:
  19. Tag_name, text_name, text_level = token. split_contents ()
  20. Except t:
  21. Raise template. templatesyntaxerror ,\
  22. "% R tag syntax error, followed by two parameters: variable name and privacy level of the variable information" % \
  23. Token. split_contents [0]
  24. Try:
  25. Text_level = int (text_level)
  26. Except t:
  27. Raise templatesyntaxerror, "permission_level tag syntax error, information privacy level should be an integer number"
  28. Sequence = parser. compile_filter (text_name)
  29. Return permissionlevel (sequence, text_level)
  30. Register. Tag ('permission _ level', do_permission_level)

 

The above code completes the function of determining the privacy level of an information, and then distinguishing whether to display or not to display according to the login user's permissions. The usage in the template is as follows:

{% Permission_level objects. Count 4%}

Permission_level is the tag name, and objects. Count is the variable or attribute passed from the view. The following 4 shows that the privacy level of this attribute (objects. Count) is 4. It is displayed only when the privacy level of the logged-on user is greater than it; otherwise, it is displayed as "XXX ".

 

Next we will analyze the above Code carefully.

Tag_name, text_name, text_level = token. split_contents ()
This statement splits {% permission_level objects. Count 4%} into three characters, where text_name is "objects. Count ". Different from the custom filter, the filter can accept non-character parameters. The type {0.123 | floatformat: 2} can also be {0.123 | floatformat: "2"}. The second parameter is enclosed in quotation marks. If no quotation marks are added, non-character objects are passed. users in the template can pass through filter. But different tags, the parameter passed by the tag to the registered function is a string.

 

At that time, the custom tags was also required by the project. However, when I started to do this, I found that the tag was passed with a string. At that time, I checked a lot of information and did not find a solution. At that time, I wanted to discard the custom tags. But do you notice that the built-in tags of Django does not pass characters, such as {% if USER %}, {% for item in test_list %, django must have any way to associate characters such as "user" and "test_list" with objects passed in the view. So I began to look at Django's source code. (You know, for cainiao like me. It is not easy to look at the source code ).

 

What magic does Django use to convert characters into objects. At first, I thought it was like this. For example, {% if USER %}, the user is extracted first, and then the user passed in is retrieved from the context, user = context ['user'], but later I thought that a single object would be okay, but how can I do it with periods. Like user. username? Is it another way to separate it through string operations, but what if there are multiple periods? Similar

User. profile. realname. Looking at the source code based on this idea, I found that this is not what I think. Some of the source code is not very understandable, but it is the key that these codes do not understand.

 

Let's look back at the above Code. The Code method for registering a tag has a parser parameter, which is exactly this parameter.

Compare the above Code.

Sequence = parser. compile_filter (text_name)
Strings such as user, user. Age, user. profile. realname, which are separated from token. split_contents () are first compiled into a sequence object. I don't quite understand how to compile it.

Then there is a sentence values = self. sequence. Resolve (context, true) in the class method)
Print out values again to see, type (values) to see, haha. It is no longer a string, but a real instance object or variable.

 

So everything is OK. Although I don't know how these two sentences are implemented in Django, I don't care. At least now we can customize the appropriate filters and tags.

Django custom tags and filters

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.