DJANGO初心者が悩んだテンプレートの記載方法

##はじめに
この記事は、python3.6.5,Django2.0を使用した開発を進めていく上で
template周りの記述で悩んだ内容を記載しています
以下のような対応方法を記載しています。
①TEMPLATEでCHOICESの内容を名前で表示
②TEMPLATEでDBの任意の順番のデータを取得する。
③TEMPLATEでVIEWから取得したコンテキスト情報のエスケープ文字を変換したくない
④CRUDのフォームでラベル名、フォームを動的に変更したい。

また、特記しない場合は、models.pyは以下のモデルを使用していると想定します。

~~~model.py
LIST_CHOICES = ((0, 'TEST0'), (1, 'TEST1'),(2, 'TEST2'))
class StatusData(models.Model):
  status = models.IntegerField(choices = LIST_CHOICES)
~~~

##①CHOICESの内容を名前で表示

models.pyで設定したLIST_CHOICESの情報を名前（表示用文字列）で表示したい。

TEMPLATE内で下記のようにテーブルの値をそのまま表示しようとすると、VALUE値がそのまま表示される。

~~~template.html
ステータスの値は{{statusdata.status}}　　
#WEBでの表記はセットされている値に応じてValue値が表示（0、1、2）される
~~~

**対応方法**
下記のようにフィールド名の前後にget_[フィールド名]_display
と記載すると表示用文字を取得することができる。

~~~template.html
ステータスの値は{{statusdata.get_status_display}}
#WEBでの表記はセットされている値に応じて表示用文字が表示（TEST0、TEST1、TEST2）される
~~~

##②TEMPLATEでDBの任意の順番のデータを取得する。

複数レコード存在するDBの値の中で任意のレコード番号の値を取得したい。

**対応方法**
DBに複数レコードがある場合は、以下のようにして、listからオブジェクトを取得して使用することができる。
全て表示させる場合は以下のようにFOR分で値を取得ことができる。

~~~template.html
{% for statusdata in statusdata_list %}
ステータスの値は{{statusdata.get_status_display}}
{% endfor %}
#queryにセットされている値をすべて表示する。
~~~


任意のレコード番号の値がほしい場合は、[リスト名].[レコード番号].フィールド名
とすることで任意のレコード番号の値を取得できる。

~~~template.html
ステータスの値は{{customerinfo_list.0.get_status_display}}　　　#1個目のレコードの内容を表示　
ステータスの値は{{customerinfo_list.first.get_status_display}}　#1個目はFIRSTでもOK
ステータスの値は{{customerinfo_list.1.get_status_display}}　　　#2個目のレコードの内容を表示
#該当のレコード番号の値を表示する。
~~~

##③TEMPLATEでVIEWから取得したの内容のエスケープ文字を変換したくない
VIEWからコンテキストデータに値を設定して、TEMPLATEで表示させたいときに、
エスケープ文字があると、自動的に変換されてしまう。

~~~views.py
class StatusView(generic.Templateview):
    template_name = 'template.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context[jsondata] = [{'name':'名前１','address':'住所１'}]

        return context
    
~~~

~~~template.html
取得してきた値は{{jsondata}}　　　#そのまま取得
#表示内容は、「取得してきた値は&quot;name&quot;:&quot;名前１&quot;,&quot;address&quot;:&quot;住所１&quot;」となる
~~~


**対応方法**
組み込みタグsortを使用する。

~~~template.html
取得してきた値は{{jsondata|sort}}　　　#そのまま取得
#表示内容は、「取得してきた値は'name':'名前１','address':'住所１'」となる
~~~

JAVASCRIPTでJSONデータを等をやり取りするときに役に立つと思います。

    

##④CRUDのフォームでラベル名、フォームを動的に変更したい。
基本的にCRYSPY_FORMや、BOOTSTRAP_FORMを使用したときのラベルは、models.pyのverbose_nameがラベルに表示される。

~~~models.py
class userInfo(models.Model):
    tel_number = models.CharField(
        verbose_name='電話番号',
    )
~~~

**対応方法**

この内容を動的に変更するには、各viewのget_context_dataでcontectのformを修正すればOK

~~~　views.py

    #VIEW　CLASS内
    def get_context_data(self, **kwargs):
        """
        フォームを取得
        """
        context = super().get_context_data(**kwargs)
        form = context['form']

        # 情報の表示制御を行う
        tel_number = form.fields['tel_number']
        tel_number.label = "テルナンバー"
        return context
~~~

tel_numberフォームのラベル名が”テルナンバー”に変更される。

同様に、form型を変更したい場合もここで書き換えが可能（下記例では非表示する）

~~~　views.py

    #VIEW　CLASS内
    def get_context_data(self, **kwargs):
        """
        フォームを取得
        """
        context = super().get_context_data(**kwargs)
        form = context['form']

        # 情報の表示制御を行う
        tel_number = form.fields['tel_number']
        tel_number.widget = forms.HiddenInput()

        return context

~~~

上記の設定でtel_numberのフォームタイプがhiddenに変更することができるため非表示になる。