mycpen

Mycpen

记录学习历程与受益知识
github
telegram
bilibili

04_Django-Template Variables/Tags/Filters/Inherit - URL Reverse Resolution

Video link: https://www.bilibili.com/video/BV1vK4y1o7jH

1. Template Layer - Variables and Tags#

Variables#

  • Python variables can be encapsulated in a dictionary in the view function and passed to the template.

Example:

def xxx_view(request):
    dic = {
        "variable1": "value1",
        "variable2": "value2",
    }
    return render(request, 'xxx.html', dic)
  • Data types that can be passed to the template:
str - string    int - integer
list - array     tuple - tuple
dict - dictionary  func - method
obj - instantiated object
  • Using variable syntax in the template:
- {{ variable_name }}
- {{ variable_name.index }}
- {{ variable_name.key }}
- {{ object.method }}
- {{ function_name }}
  • Demonstration:
http://127.0.0.1:8000/test_html_param

image-20220216013835514

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    path('test_html', views.test_html)
]


# mysite1/mysite1/views.py
def test_html_param(request):
    dic = {}
    dic['int'] = 88
    dic['str'] = 'peng'
    dic['lst'] = ['Tom', 'Jack', 'Lily']
    dic['dict'] = {'a':9, 'b':8}
    dic['func'] = say_hi
    dic['class_obj'] = Dog()
    dic['script'] = '<script>alert(1111)</script>'
    return render(request, 'test_html_param.html', dic)

def say_hi():
    return 'hahaha'

class Dog:
    def say(self):
        return 'wangwang'


# mysite1/templates/test_html_param.html
<h3>int is {{ int|add:"2" }}</h3>
<h3>str is {{ str|upper }}</h3>
<h3>lst is {{ lst }}</h3>
<h3>lst is {{ lst.0 }}</h3>
<h3>dict is {{ dict }}</h3>
<h3>dict['a'] is {{ dict.a }}</h3>
<h3>function is {{ func }}</h3>
<h3>class_obj is {{ class_obj.say }}</h3>
<h3>script is {{ script|safe }}</h3>

Tags#

Template Tags

  • Purpose: Embed some server-side functionality into the template, such as flow control, etc.
  • Tag syntax:
{% tag %}
...
{% endtag %}

if Tag#

  • Syntax:
{% if condition_expression1 %}
...
{% elif condition_expression2 %}
...
{% elif condition_expression3 %}
...
{% else %}
...
{% endif %}  - Needs an end tag
  • Note:
  1. The operators that can be used in the if condition expression are ==, !=, <, >, <=, >=, in, not in, is, is not, not, and, or.
  2. Using actual parentheses in if tags is invalid syntax. If you need them to indicate precedence, you should use nested if tags.

Official documentation: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#if

  • Demonstration:
http://127.0.0.1:8000/test_if_for

image-20220216020405259

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    path('test_if_for', views.test_if_for),
]

# mysite1/mysite1/views.py
def test_if_for(request):
    dic = {}
    dic['x'] = 20
    dic['lst'] = ['Tom', 'Jack', 'Lily']
    return render(request, 'test_if_for.html', dic)

# mysite1/templates/test_if_for.html
{% if x > 10 %}
The weather is nice today
{% else %}
The weather is very nice today
{% endif %}

<br>

{% for name in lst %}
    {% if forloop.first %} &&&&& {% endif %}
    <p> {{ forloop.counter }}  {{ name }}</p>
    {% if forloop.last %} ===== {% endif %}
{% empty %}
    No data available
{% endfor %}
  • Template Tag - if Tag - Exercise

    Write a simple calculator page that can perform basic addition, subtraction, multiplication, and division calculations on the server side (needs to remember the user's last input state and dropdown selection state).

    image-20220216020922893

    • Frontend reference code:

      image-20220216021536197

    • Demonstration:

    http://127.0.0.1:8000/mycal
    

    image-20220216023528956

    # mysite1/mysite1/urls.py
    urlpatterns = [
        ...
        path('mycal', views.test_mycal),
    ]
    
    
    # mysite1/mysite1/views.py
    def test_mycal(request):
        if request.method == 'GET':
            return render(request, 'mycal.html')
        elif request.method == 'POST':
            # Handle calculation
            x = int(request.POST['x'])
            y = int(request.POST['y'])
            op = request.POST['op']
    
            result = 0
            if op == 'add':
                result = x + y
            elif op == 'sub':
                result = x - y
            elif op == 'mul':
                result = x * y
            elif op == 'div':
                result = x / y
    
            # dic={'x':x, 'y':y, 'op':op}
            return render(request, 'mycal.html', locals())  # locals method - encapsulates local variables into a dictionary (Python built-in method)
    
    # mysite1/templates/mycal.html
    <form action='/mycal' method='post'>
        <input type='text' name="x" value="{{ x }}">
        <select name='op'>
        <option value="add"  {% if op == 'add' %}selected{% endif %} > +Add</option>  # ☆ Record op state, option selected attribute, used if tag
        <option value="sub"  {% if op == 'sub' %}selected{% endif %}> -Subtract</option>
        <option value="mul"  {% if op == 'mul' %}selected{% endif %}> *Multiply</option>
        <option value="div"  {% if op == 'div' %}selected{% endif %}> /Divide</option>
        </select>
        <input type='text' name="y" value="{{ y }}"> = <span>{{ result }}</span>
        <div><input type="submit" value='Start Calculation'></div>
    </form>
    
    

for Tag#

image-20220216024655125

  • Demonstration:
http://127.0.0.1:8000/test_if_for

image-20220216025446396

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    path('test_if_for', views.test_if_for),
]

# mysite1/mysite1/views.py
def test_if_for(request):
    dic = {}
    dic['lst'] = ['Tom', 'Jack', 'Lily']
    return render(request, 'test_if_for.html', dic)

# mysite1/templates/test_if_for.html
{% for name in lst %}
    {% if forloop.first %} &&&&& {% endif %}
    <p> {{ forloop.counter }}  {{ name }}</p>
    {% if forloop.last %} ===== {% endif %}
{% empty %}
    No data available
{% endfor %}

Summary#

  • Variable calling - dot notation
  • Tag syntax {% raw %}{% tag %} {% endtag %}{% endraw %}

2. Template Layer - Filters and Inheritance#

Filters#

  • Definition: Process the value of a variable when outputting the variable.
  • Purpose: You can change the output display of a variable by using filters.
  • Syntax: {% raw %}{{ variable | filter1:'parameter1' | filter2:'parameter2' ... }}{% endraw %}

Official documentation: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/

  • Common filters:

    image-20220216030721308

  • Demonstration:

http://127.0.0.1:8000/test_html_param

image-20220216031236417

image-20220216031311962

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    path('test_html', views.test_html)
]


# mysite1/mysite1/views.py
def test_html_param(request):
    dic = {}
    dic['int'] = 88
    dic['script'] = '<script>alert(1111)</script>'
    return render(request, 'test_html_param.html', dic)

def say_hi():
    return 'hahaha'

class Dog:
    def say(self):
        return 'wangwang'


# mysite1/templates/test_html_param.html
<h3>int is {{ int|add:"2" }}</h3>
<h3>str is {{ str|upper }}</h3>
<h3>script is {{ script|safe }}</h3>

Inheritance#

Template Inheritance

​ As shown in the example:

image-20220216032123690

  • Template inheritance allows the reuse of content from the parent template, and the child template directly inherits all content from the parent template and can override the corresponding blocks in the parent template.

  • Syntax - In the parent template:

    • Define block tags in the parent template
    • Indicate which parts can be modified in the child template
    • block tag: defined in the parent template, can be overridden in the child template
  • Syntax - In the child template:

    • Inherit template using extends tag (written on the first line of the template file)

      For example {% extends 'base.html' %}

    • Child template rewrites the content block in the parent template

      {% block block_name %}
      Child template block used to override the content of block_name in the parent template
      {% endblock block_name %}  - block_name can be written or not
      
  • Overriding rules

    • If not overridden, it will display according to the effect in the parent template.
    • If overridden, it will display according to the overriding effect.
  • Note

    • When inheriting templates, dynamic content from the server side cannot be inherited.
  • Demonstration:

http://127.0.0.1:8000/base_index

image-20220216150400013

image-20220216150430581

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    path('base_index', views.base_view, name='base_index'),
    path('music_index', views.music_view),
    path('sport_index', views.sport_view),
]

# mysite1/mysite1/views.py
def base_view(request):
    lst = ['Tom', 'Jack']
    return render(request, 'base.html', locals())

def music_view(request):
    return render(request, 'music.html')

def sport_view(request):
    return render(request, 'sport.html')

#-------------------------------------------------------------
# mysite1/templates/base.html   # Parent template
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block mytitle %}
    <title>Home</title>           # Place that can be modified by child template
    {% endblock %}
</head>
<body>
{{ lst }}                      # Child template cannot inherit variables (dynamic content)
<a href="/music_index">Music Channel</a>   # Child template cannot modify
<a href="/sport_index">Sports Channel</a>
<br>


{% block info %}
    This is the homepage                  # Place that can be modified by child template
{% endblock %}

<br>

<h3>Contact xxxx for any questions</h3>  # Child template cannot modify


# mysite1/templates/music.html   # Child template
{% extends 'base.html' }            # Inherit parent template

{% block mytitle %}
    <title>Music Channel</title>      # Child template rewrites block
{% endblock %}

{% block info %}
    Welcome to the Music Channel
{% endblock %}

# mysite1/templates/sport.html
{% extends 'base.html' %}

{% block mytitle %}
    <title>Sports Channel</title>
{% endblock %}

{% block info %}
    Welcome to the Sports Channel
{% endblock %}

Summary#

  • Filters

    { variable | filter1:'parameter_value1' | filter2:'parameter_value2' ... }

  • Template Inheritance

    Parent template - define modifiable blocks

    Child template - inherit parent template; modify blocks defined in parent template as needed.


3. URL Reverse Resolution#

  • Where URLs appear in the code

    1. ==Template== 【in HTML】

      1. <a ==href==='url'>Hyperlink</a>

        Clicking will redirect the page to the URL.

      2. <form ==action==='url' method='post'>

        Data in the form will be submitted to the URL using the post method.

    2. In the ==view function== - 302 redirect HttpResponseRedirect('url')

      Redirects the address in the user's address bar to the URL.

  • URL writing specifications in the code

    1. ==Absolute address==

      http://127.0.0.1:8000/page/1

    2. ==Relative address==

      1. '==/==page/1' - =='/' prefixed relative address==, the browser will add the protocol, IP, and port from the current address bar to this address as the final access address, that is, if the current page address bar is http://127.0.0.1:8000/page/3; the current relative address will ultimately result in ==http://127.0.0.1:8000== + /page/1 (☆ High frequency usage)
      2. 'page/1' - ==Relative address without '/' prefix==, the browser will append this relative address to the content before the last '/' of the current URL as the final access address. For example, if the current address bar is ==http://127.0.0.1:8000/topic/==detail; then the final result of this relative address will be ==http://127.0.0.1:8000/topic/== + page/1
  • Demonstration:

http://127.0.0.1:8000/test/url

image-20220216165641996

image-20220216165734057

image-20220216170206874

# mysite1/mysite1/urls.py
urlpatterns = [
    ...
    # http://127.0.0.1:8000/test/url
    path('test/url', views.test_url),
    path('test_url_result', views.test_url_result)
]


# mysite1/mysite1/views.py
def test_url(request):
    return render(request, 'test_url.html')

def test_url_result(request):
    return HttpResponse('---test url res is ok')


# mysite1/templates/test_url.html
<a href="http://127.0.0.1:8000/test_url_result">Absolute address</a>
<a href="/test_url_result">Relative address with '/'</a>
<a href="test_url_result">Relative address without '/'</a>   # Browser resolves to http://127.0.0.1:8000/test/test_url_result

  • URL Reverse Resolution

    • URL reverse resolution refers to dynamically finding or calculating the corresponding route using the ==name defined in the path== in the view or template.

    • Syntax of the path function

      • path(route, views, ==name==="alias")
      • path('page', views.page_view, name="page_url")
      • The unique name determined by the 'name=' keyword in the path can be used to reverse infer this URL information in the template or view.
    • In the ==template== - Reverse resolution of the address is achieved through the URL tag.

      {% url 'alias' %}
      {% url 'alias' 'parameter1' 'parameter2' %}
      ex:
      {% url 'pagen' '400' %}      --- All parameters are strings
      {% url 'person' age='18' name='gxn' %}
      
      • Demonstration: Using in the template
      http://127.0.0.1:8000/test/url
      

      image-20220216172535944

      # mysite1/mysite1/urls.py
      urlpatterns = [
          ...
          # http://127.0.0.1:8000/test/url
          path('test/url', views.test_url),
          path('test_urls_result/<int:age>', views.test_url_result, name='tr')   # Alias tr
      ]
      
      # mysite1/mysite1/views.py
      def test_url(request):
          return render(request, 'test_url.html')
      
      def test_urls_result(request):
          return HttpResponse('---test url res is ok')
      
      # mysite1/templates/test_url.html
      <a href="{% url 'tr' '100' %}">URL reverse resolution version</a>   # ☆ Using alias in the template
      
      
    • In the ==view function== → You can call the ==reverse== method in Django for reverse resolution.

      from django.urls import reverse
      reverse('alias', args=[], kwargs={})
      ex:
      print(reverse('pagen', args=[300]))
      print(reverse('person', kwargs=
      {'name':'peng', 'age':23}))
      
      
      • Demonstration:

        http://127.0.0.1:8000/test/url
        
        # 302 redirect - the location tag in the response header indicates the redirect address
        

        image-20220216174234729

        image-20220216174547656

        # mysite1/mysite1/urls.py
        urlpatterns = [
            ...
            path('base_index', views.base_view, name='base_index'),   # Alias base_index
            # http://127.0.0.1:8000/test/url
            path('test/url', views.test_url),
            path('test_urls_result/<int:age>', views.test_url_result, name='tr')   # Alias tr
        ]
        
        
        # mysite1/mysite1/views.py
        def base_view(request):
            lst = ['Tom', 'Jack']
            return render(request, 'base.html', locals())
        
        def test_url(request):
            return render(request, 'test_url.html')
        
        def test_url_result(request, age):
            # 302 redirect
            from django.urls import reverse
            url = reverse('base_index')   # ☆ Using alias in the view function
            return HttpResponseRedirect(url)
        
        
        #---------------------------------------------------------------
        # mysite1/templates/test_url.html
        <a href="{% url 'tr' '100' %}">URL reverse resolution version</a>
        
        # mysite1/templates/base.html
        Omitted
        

4. Summary#

  • Request (request) and Response (HttpResponse)
  • GET/POST handling - request.GET/POST
  • MVC and MTV
  • Basic configuration of the template layer
  • Template variables/tags/filters/inheritance
  • URL reverse resolution

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.