"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

Views.pyでHTMLを組み立てて、エスケープさせないでFormに渡す方法/django2.0

djangoのForm入力をviews.pyでチェックして、再入力を即すという処理をするときに忘れがちな部分を、備忘を兼ねてまとめておきます。

f:id:arakan_no_boku:20190320212948j:plain

 

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

 

入力フォームに文章等を入力して、サーバーサイドでチェックをして再入力させる。

非常によくあるパターンです。

例えば、以下のような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の中に複数書くことになります。

知ってれば簡単なことです。 

djangoを継続的にさわっている時はいいんですが、他の言語とかをしばらく使ってて、djangoに戻ってきた時に、思わず「valueプロパティ」なんぞに渡そうとしてエラーになってから気づく・・ってのが、まま、あったりするんですよね。

 

views.pyでHTMLを組み立ててエスケープさせない

 

サーバーサイドで文章などをチェックした時に、チェックエラーになった箇所をハイライトして示したい・・なんて要求がたまにあります。

 こんな感じで。

f:id:arakan_no_boku:20190325005228j:plain

こういう場合、ハイライトしたい箇所を示すために「HTMLタグ」を埋め込んで、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」を利用することが多いです。

 

safeをつける

 

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

例えば

{{rets}}

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

{{ rets|safe }}

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

 

autoescapeをOFFにする

 

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

例えば

{{rets}}

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

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

ですね。

 

まとめ

 

ごくごく基本的ですが、django独特の作法を要求される部分でもあるのかな・・と個人的には思ってます。

なので、自分のようにメイン言語が複数あって、あっちにふらふら・こっちにふらふらしている人間だと、久しぶりの時に「あれっ」っとなりがちなとこでもあります。

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

ではでは。