mycpen

Mycpen

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

04_Django-テンプレート変数/タグ/フィルター/継承-url逆引き解析

動画リンク:https://www.bilibili.com/video/BV1vK4y1o7jH

一。テンプレート層 - 変数とタグ#

変数#

  • ビュー関数内で Python 変数を 辞書 に封装してテンプレートに渡すことができます

例:

def xxx_view(request):
    dic = {
        "変数1": "値1",
        "変数2": "値2",
    }
    return render(request, 'xxx.html', dic)
  • テンプレートに渡すことができる データ型
str-文字列	int-整数
list-配列	tuple-タプル
dict-辞書	func-メソッド
obj-クラスインスタンス化されたオブジェクト
  • テンプレート内での変数の使用法
- {{ 変数名 }}
- {{ 変数名.index }}
- {{ 変数名.key }}
- {{ オブジェクト.メソッド }}
- {{ 関数名 }}
  • デモ:
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 は {{ int|add:"2" }}</h3>
<h3>str は {{ str|upper }}</h3>
<h3>lst は {{ lst }}</h3>
<h3>lst は {{ lst.0 }}</h3>
<h3>dict は {{ dict }}</h3>
<h3>dict['a'] は {{ dict.a }}</h3>
<h3>function は {{ func }}</h3>
<h3>class_obj は {{ class_obj.say }}</h3>
<h3>script は {{ script|safe }}</h3>

タグ#

テンプレートタグ

  • 目的:サーバー側の機能をテンプレートに埋め込むこと、例えばフロー制御など
  • タグ構文:
{% タグ %}
...
{% 終了タグ %}

if タグ#

  • 構文
{% if 条件式1 %}
...
{% elif 条件式2 %}
...
{% elif 条件式3 %}
...
{% else %}
...
{% endif %}	- 終了タグが必要
  • 注意
  1. if 条件式で使用できる演算子 ==, !=, <,> , <=, >=, in, not in, is, is not, not、and、or
  2. if タグ内で実際の括弧を使用することは無効な構文です。優先順位を示す必要がある場合は、ネストされた if タグを使用する必要があります。

公式ドキュメント:https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/#if

  • デモ:
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 %}
今日は天気が良い
{% else %}
今日はとても良い天気です
{% endif %}

<br>

{% for name in lst %}
    {% if forloop.first %} &&&&& {% endif %}
    <p> {{ forloop.counter }}  {{ name }}</p>
    {% if forloop.last %} ===== {% endif %}
{% empty %}
    現在データがありません
{% endfor %}
  • テンプレートタグ - if タグ - 演習

    簡単な計算機ページを作成し、サーバー側で簡単な加減乗除計算を行う(ユーザーの前回の入力状態、ドロップダウンリストの選択状態を記録する必要があります)

    image-20220216020922893

    • フロントエンド参考コード:

      image-20220216021536197

    • デモ:

    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':
            #計算処理
            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メソッド-ローカル変数を辞書に直接封装(Pythonの組み込みメソッド)
    
    # 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 %} > +加算</option>	# ☆ op状態を記録し、option selected属性を使用したifタグ
        <option value="sub"  {% if op == 'sub' %}selected{% endif %}> -減算</option>
        <option value="mul"  {% if op == 'mul' %}selected{% endif %}> *乗算</option>
        <option value="div"  {% if op == 'div' %}selected{% endif %}> /除算</option>
        </select>
        <input type='text' name="y" value="{{ y }}"> = <span>{{ result }}</span>
        <div><input type="submit" value='計算を開始'></div>
    </form>
    
    

for タグ#

image-20220216024655125

  • デモ:
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 %}
    現在データがありません
{% endfor %}

小節#

  • 変数呼び出し - ドット法
  • タグ構文 {% raw %}{% タグ %} {% 終了タグ %}{% endraw %}

二。テンプレート層 - フィルターと継承#

フィルター#

  • 定義:変数出力時に変数の値を処理する
  • 目的:フィルターを使用して変数の出力表示を変更できる
  • 構文:{% raw %}{{変数 | フィルター 1:' 引数 1' | フィルター 2:' 引数 2' ...}}{% endraw %}

公式ドキュメント:https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/

  • 一般的なフィルター:

image-20220216030721308

  • デモ:
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 は {{ int|add:"2" }}</h3>
<h3>str は {{ str|upper }}</h3>
<h3>script は {{ script|safe }}</h3>

継承#

テンプレートの継承

​ 以下の例:

image-20220216032123690

  • テンプレート継承により、親テンプレートの内容を再利用でき、子テンプレートは親テンプレートのすべての内容を直接継承し、親テンプレートの対応するブロックを上書きできます

  • 構文 - 親テンプレート内:

    • 親テンプレート内で ** ブロック block ** タグを定義
    • 子モジュール内で変更可能なものを示す
    • block タグ:親テンプレート内で定義され、子テンプレート内で上書き可能
  • 構文 - 子テンプレート内:

    • テンプレートを継承する extends タグ(テンプレートファイルの最初の行に記述)

      例: {% extends 'base.html' %}

    • 子テンプレートが親テンプレート内の内容ブロックを上書きする

      {% block block_name %}
      子テンプレートブロックは親テンプレート内の block_name ブロックの内容を上書きするためのものです
      {% endblock block_name %}	- block_nameは書いても書かなくても良い
      
  • 上書きのルール

    • 上書きしない場合、親テンプレートの効果が表示される
    • 上書きする場合、上書き効果が表示される
  • 注意

    • テンプレート継承時、サーバー側の動的内容は継承できない
  • デモ:

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		# 親テンプレート
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block mytitle %}
    <title>ホームページ</title>				# 子テンプレートが変更できる場所
    {% endblock %}
</head>
<body>
{{ lst }}								# 子テンプレートは変数(動的内容)を継承できない
<a href="/music_index">音楽チャンネル</a>		# 子テンプレートは変更できない
<a href="/sport_index">スポーツチャンネル</a>
<br>


{% block info %}
    これはホームページです							# 子テンプレートが変更できる場所
{% endblock %}

<br>

<h3>何か問題があればxxxxに連絡してください</h3>				# 子テンプレートは変更できない


# mysite1/templates/music.html		# 子テンプレート
{% extends 'base.html' %}				# 親テンプレートを継承

{% block mytitle %}
    <title>音楽チャンネル</title>				# 子テンプレートがblockを上書き
{% endblock %}

{% block info %}
    音楽チャンネルへようこそ
{% endblock %}

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

{% block mytitle %}
    <title>スポーツチャンネル</title>
{% endblock %}

{% block info %}
    スポーツチャンネルへようこそ
{% endblock %}

小節#

  • フィルター

    { 変数 | フィルター1:'引数値1' | フィルター 2:' 引数値 2' ... }

  • テンプレートの継承

    親テンプレート - 変更可能なblockを定義

    子テンプレート - 親テンプレートを継承;必要に応じて親テンプレートで定義されたblockを変更


三. URL 逆引き#

  • コード内の URL 出現位置

    1. == テンプレート == 【html 内】

      1. <a ==href==='url'> ハイパーリンク </a>

        クリック後 ページが url にジャンプします

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

        form フォーム内のデータを post メソッドで url に送信します

    2. == ビュー関数 == 内 - 302 リダイレクト HttpResponseRedirect ('url')

      ユーザーのアドレスバー内のアドレスを url にリダイレクトします

  • コード内の URL 記述規範

    1. == 絶対アドレス ==

      http://127.0.0.1:8000/page/1

    2. == 相対アドレス ==

      1. '==/==page/1' - =='/' で始まる相対アドレス ==、ブラウザは現在のアドレスバーの プロトコル、ip と ポート をこのアドレスに加え、最終的なアクセスアドレスとして、つまり現在のページのアドレスバーが http://127.0.0.1:8000/page/3 の場合;現在の相対アドレスの最終結果は ==http://127.0.0.1:8000== + /page/1 (☆ 高頻度使用)
      2. 'page/1' - == '/' で始まらない相対アドレス ==、ブラウザは現在のurlの最後の / の前の内容にこの相対アドレスを加え 最終的なアクセスアドレスを生成します。例えば現在のアドレスバーのアドレスが ==http://127.0.0.1:8000/topic/==detail の場合、この相対アドレスの最終結果は ==http://127.0.0.1:8000/topic/== + page/1
  • デモ:

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">絶対アドレス</a>
<a href="/test_url_result">'/'付きの相対アドレス</a>
<a href="test_url_result">'/'無しの相対アドレス</a>		# ブラウザは http://127.0.0.1:8000/test/test_url_result に解析します

  • URL 逆引き

    • URL 逆引きとは、ビューまたはテンプレート内で ==path で定義された名前 == を使用して == 動的に対応するルートを検索または計算する == ことを指します

    • path 関数の構文

      • path (route, views, ==name==="エイリアス")
      • path('page', views.page_view, name="page_url")
      • path 内の 'name=' キーワードによって一意の名前が決定され、テンプレートまたはビュー内でこの名前を使用して逆にこの url 情報を推測できます
    • == テンプレート内 == - url タグを使用してアドレスの逆引きを実現します

      {% url 'エイリアス' %}
      {% url 'エイリアス' '引数1' '引数2' %}
      例:
      {% url 'pagen' '400' %}		--- 引数はすべてstr
      {% url 'person' age='18' name='gxn' %}
      
      • デモ:テンプレート内で使用
      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')		# エイリアス 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逆引きバージョン</a>								# ☆ テンプレート内でエイリアスを使用
      
      
    • == ビュー関数 == 内 → django の ==reverse== メソッドを呼び出して逆引きを行います

      from django.urls import reverse
      reverse('エイリアス', args=[], kwargs={})
      例:
      print(reverse('pagen', args=[300]))
      print(reverse('person', kwargs=
      {'name':'peng', 'age':23}))
      
      
      • デモ:

        http://127.0.0.1:8000/test/url
        
        # 302リダイレクト - レスポンスヘッダー内のlocationマークのリダイレクト先
        

        image-20220216174234729

        image-20220216174547656

        # mysite1/mysite1/urls.py
        urlpatterns = [
            ...
            path('base_index', views.base_view, name='base_index'),						# エイリアス 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')		# エイリアス 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リダイレクト
            from django.urls import reverse
            url = reverse('base_index')													# ☆ ビュー関数内でエイリアスを使用
            return HttpResponseRedirect(url)
        
        
        #---------------------------------------------------------------
        # mysite1/templates/test_url.html
        <a href="{% url 'tr' '100' %}">URL逆引きバージョン</a>
        
        # mysite1/templates/base.html
        
        
        

四。まとめ#

  • リクエスト(request)とレスポンス(HttpResponseqing)
  • GET/POST 処理 - request.GET/POST
  • MVC と MTV
  • テンプレート層の基本設定
  • テンプレート変数 / タグ / フィルター / 継承
  • URL 逆引き

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。