"BOKU"のITな日常

興味のむくまま気の向くままに調べたり・まとめたりしてます。

サーバーサイドからForm部品に文字列を返す&HTMLをエスケープさせない方法/django3.

f:id:arakan_no_boku:20190320212948j:plain

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

目次

1.フォームに入力した値を画面遷移後に再表示する

 

例えば、以下のような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)を定義して、これを初期表示する場合の「views.py」の書き方はこんな感じ。

        form = forms.UserForm(label_suffix=':')
        c = {'form': form}
        

この場合は、未入力状態でテキストエリアが表示されます。

そこに文章を入力して、SUBMITボタンを押した場合、入力された文章内容はサーバーサイド(views.py)では以下のように受け取ることになります。

textone = request.POST["textone"]

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

valueとかのプロパティを探してしまいそうになりますが、djangoのお作法としては、以下のように、「initial」で渡します。

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

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

2.views.pyで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独特の作法で勘違いしやすいと個人的に思っている部分です。

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

ではでは。