SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

PythonからDjango3テンプレートのForm部品に文字列を渡す場合の注意点

f:id:arakan_no_boku:20190320212948j:plain

目次

 views.pyから、HTML側(テンプレート)に文字列を返す場合の注意点2つです。

サーバーサイドからForm部品に文字列を返す

画面入力した値を、画面遷移後の画面に表示させたい場合などが該当します。

入力された値を画面遷移後に渡すための、Djangoのお作法がありますよという話です。

そのお作法とは。

例えば、以下のようなFormを「forms.py」で定義している場合。

from django import forms

class UserForm(forms.Form):
     textone = forms.CharField(label='元文章',max_length=500,min_length=1,widget=forms.Textarea(attrs={'id': 'commu','placeholder':'ここに文章を入力してください。'}))

UserFormクラス に「textone」という名前のCharField(Textarea)を定義している想定として、そこに文章を入力して、SUBMITボタンを押した場合、入力された文章内容はサーバーサイド(views.py)では以下のように受け取ることになります。

textone = request.POST["textone"]

なので、入力内容を保持したまま、もう一度フォームを表示してやるには、フォームの初期値として、受け取った「textone」の内容を渡してやらねばなりません。

その際のdjangoのお作法は、以下のように、「initial」でformにセットして、まとめて渡すやり方になります。

        textone = request.POST["textone"]
        form = forms.UserForm(initial={'textone' : textone})
        c = {'form': form}

もちろん、複数のFieldを定義していて、それらにも渡す時には、initialの中に複数書くわけです。

HTMLを組み立ててエスケープさせない方法

サーバーサイドで文章などをチェックして、チェックエラーになった箇所をハイライトして示す場合等に必要になります。

f:id:arakan_no_boku:20190325005228j:plain

例えば、上記のようなことを実現しようとしたとき、ハイライトしたい箇所を示すために「HTMLタグ」を埋め込んで渡したくなります。

上記の場合だと、こういうHTMLです。

サーバーサイドで文章などをチェックした時に、チェックエラーになった箇所をハイライトして示したい <span class="mark font-weight-bold text-danger">・</span> <span class="mark font-weight-bold text-danger">・</span> な <span class="mark font-weight-bold text-danger">ん</span> て要求がたまにあります。 

ところが、HTML側で{{変数名}}で受けると、自動的にエスケープされます。

そうすると、以下のような表示になってしまって、ハイライトされません。

疑わしい部分と判定した箇所あります。&lt;/br&gt;ハイライトされた箇所を確認してください。&lt;/br&gt;&lt;hr&gt;サーバーサイドで文章などをチェックした時に、チェックエラーになった箇所をハイライトして示したい &lt;span class=&quot;mark font-weight-bold text-danger&quot;&gt;・&lt;/span&gt; &lt;span class=&quot;mark font-weight-bold text-danger&quot;&gt;・&lt;/span&gt; な &lt;span class=&quot;mark font-weight-bold text-danger&quot;&gt;ん&lt;/span&gt; て要求がたまにあります。

上記のHTMLが「rets」という変数に収められている場合、HTMLをエスケープさせないためには、以下のいずれかを行う必要があります。

どちらが有利ってことはないのですが、個人的にはタイプ量が少ない「safe」を利用することが多いです。

方法1:safeをつける 

{{変数名}}の変数名の横に「|safe」をつける方法です。

例えば

{{rets}}

エスケープされるのを抑制したい場合は

{{ rets|safe }}

みたいにしたら、HTMLがそのまま処理されるようになります。 

方法2:autoescapeをOFFにする 

{{変数名}}を、「{% autoescape off %}」と「{% endautoescape %}」で囲む方法です。

例えば

{{rets}}

エスケープされるのを抑制したい場合は

{% autoescape off %}
{{ rets }}
{% endautoescape %}

です。 

以上、ごくごく基本的ですが、django独特の作法で勘違いしやすいと個人的に思っている部分です。

あえて備忘メモを兼ねて書いてみました。

ではでは。