template
Python3
Django2.0

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':'名前1','address':'住所1'}]

        return context

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

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

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

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に変更することができるため非表示になる。