Django -- configuration and usage of mako

Posted by lordphilippe on Fri, 12 Nov 2021 14:29:56 +0100

1, Foreword

mako's biggest feature is that it allows Python code to be written freely in HTML. It's very exciting to stand up!!

2, Preparation stage

Create a new project mako_project, create a new app called app, and then install mako (to be installed online)

pip install mako

Then register the app, configure templates and static files, which will not be repeated here.

In fact, when configuring mako, you do not need to do special processing on settings, but mainly on render. You need to rewrite the render method.
Create a base under the app folder_ render.py
Write the following code:

#coding:utf-8

from mako.lookup import TemplateLookup  # Import profile
from django.template import RequestContext
from django.conf import settings  # Introduce django's settings
from django.template.context import Context
from django.http import HttpResponse


def render_to_response(request, template, c=None):  # Considering that some parameters may be passed in, a c is added here, which is empty by default
    context_instance = RequestContext(request)  # An instance
    path = settings.TEMPLATES[0]['DIRS'][0]  # Introduce TEMPLATES in settings. Because TEMPLATES is an array, we only need to take [0]
    # TEMPLATES[0] is a dictionary. Take the value of key = 'DIRS' as a list, and then take [0], which is the address of templates
    lookup = TemplateLookup(
        directories=[path],
        output_encoding='utf-8',
        input_encoding='utf-8'
    )  # The directory of template is path, and then set the input and output format, which are utf-8
    mako_template = lookup.get_template(template)  # Import template
    
    if context_instance:  # Determine whether the instance exists
        context_instance.update(c)
    else:
        context_instance = Context(c)  # If there is no context, it is created here and the required data is passed in
        
    data = {}
    
    for d in context_instance:
        data.update(d)
    
    # Create csrf_token, not in mako
    data['csrf_token'] = '<input type="hidden" name="csrfmiddlewaretoken" value="{0}" />'.format(request.META['CSRF_COOKIE'])
    
    return HttpResponse(mako_template.render(**data))

In view.py

#coding:utf-8

from django.views.generic import View
from .base_render import render_to_response

class Test(View):
    TEMPLATE = 'test.html'

    def get(self, request):
        
        return render_to_response(request, self.TEMPLATE)

Then register the route in urls

from app.views import Test

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test/', Test.as_view())
]

Run it and report an error.

other_dict must be a mapping (dictionary-like) object.

The main problem appears in parameter C: context_instance.update(c), C needs to be a dictionary, so we can judge that if C is empty, let C = an empty dictionary {}. It is not recommended to let C be an empty dictionary when defining functions, which will have security risks.

    if not c:
        c = {}

3, Preparation of Mako module

Add data to views

    def get(self, request):

        data = {'name': 'cong', 'age': 18}

        return render_to_response(request, self.TEMPLATE, data)

The writing format of HTML in mako is different. Here is * * ${}**

The power of mako is that it can completely use Python language:

<%!
    from django.conf import settings

%>

${settings.TEMPLATES[0]['DIRS'][0]}


This address was brought over.

But still% for% endfor...
Write another for loop

%for i in range(20):
    <input type="text" value="${i}" />
%endfor


You can also write a function yourself

<%
    def name():
        return 'my name is cong'
%>

<input style="display:block" type="text" name="username" value="${name()}" />


You can still inherit the template
All template inheritance is in the form of functions.
Here, self. Means that this function is in the current HTML.
You can also nest calls to functions
Note: after defining, you must call the function again before you can use it!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>${self.title()}</title>
</head>
<body>
    ${self.content()}
    ${self.js()}
</body>
</html>
<%def name="content()">
    ${self.main()}
</%def>
<%def name="main()"></%def>
<%def name="title()"></%def>
<%def name="js()"></%def>
<%def name="css()"></%def>

How to inherit in html:

<%inherit file="base.html" />

Use template

<%def name="main()">
<h1>hello mako</h1>
</%def>

<%inherit file="base.html" />

<%def name="main()">
<h1>hello mako</h1>
</%def>

<%def name="js()">
<script src="https://cdn.bootcss.com/jquery/2.2.0/jquery.js"></script>

</%def>
<%def name="title()">test...dazzy</%def>

In html, the order of calling function is arbitrary, and the location of function is determined according to the definition of base template.

4, HTML nesting and value passing

Create a new extend.html file

<%page args="local_content" />

<textarea>
    ${local_content}
</textarea>

In this way, you can find a local in other pages_ Content, and then pass in the value and display it.

Then, in the main function of index.html, give local_content incoming value:

<%def name="main()">
<%include file="extend.html" args="local_content='Hello mako'" />

<h1>hello mako</h1>
</%def>


Usage scenario: when publishing information, it is used in many HTML files, and the files transmitted from different HTML are also different.
In this way, you can share an HTML template and pass in values at will.

5, Static file import

Create a new test.css in the static folder

* {
    background-color: pink;
}

html

<%def name="css()">
<link rel="stylesheet" href="/static/test.css" />
</%def>


If you have a common css file, you can pass it in directly in base.html.
By inheriting the base template, each HTML will have the most original css style.

Topics: Python Django Back-end