質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

django views内でテンプレートに渡すコンテキストに模擬的なフィールドを追加できますか?

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 601

score 20

前提・実現したいこと

ビュー内でオブジェクトの状況に合わせて異なるメッセージをテンプレートに表示したいです。
(テンプレート内で{% if xyz... %} でメッセージを振り分けることも可能だと思いますが、分岐の数が多かったりするとHTML文が冗長になることと、読み込み速度が遅くなるかと思いエンドサイドで処理したいと思い質問しました。)

下記のソースでは、context['candidates']にviewsでフィルダーで該当したPersonモデルが格納されていると思います。そのPersonモデルの send_to_companyフィールドの状態に応じて、異なるメッセージをコンテキストに格納されている各Personモデルごとに付与してあげたいです。
最終的に、HTMLテンプレート内で add_message みたいな追加の疑似てきなフィールドを追加できたらしてみたいのですが、これは可能でしょうか?

可能なら記述の方法も教えていただきたいです。

{% for candidate in 'candidates' %}
{{candidate.birthday}}
{{candidate.add_message}} <= view内で作成したフィールド
{% endfor %}

該当のソースコード

モデル
class Person(models.Model):

    OPEN_CLOSE = (
        ('1', _('非公開')),
        ('2', _('公開')),
    )
    user = CharField('ユーザー名', max_length=120, null=True)
    birthday = models.DateField(_('生年月日'))
    apply_company = models.ForeignKey('Company',verbose_name=_('応募先'),on_delete=models.CASCADE,null=True,blank=True)画'),blank=True,null=True)
    send_to_company = CharField(_('履歴書公開許可'),choices=OPEN_CLOSE,default='1',blank=True,max_length=30)
    def __str__(self):
        return self.user

class Company(models.Model):
    user = CharField('ユーザー名', max_length=120, null=True)
    corp_name = CharField(_('企業名'), max_length=100)
    hp = CharField(_('ホームページ'),max_length=260, blank=True,null=True)
    created_at = DateTimeField('登録日', default=timezone.now)
    def __str__(self):
        return self.corp_name

ビュー
def candidates_manager(request):
    user = request.user
    company = Company.objects.get(user=user.username)
    candidates = Person.objects.filter(apply_company=company)
    context={'candidates':candidates,}
    return render(request,'company/candidates_manager.html',context)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

これでどうでしょうか。

def candidates_manager(request):
    user = request.user
    company = Company.objects.get(user=user.username)
    candidates = []
    add_message = ""
    for p in Person.objects.filter(apply_company=company):
        candidates.append([p,add_message])
    context={'candidates': candidates,}
    return render(request,'company/candidates_manager.html',context)
{% for candidate in 'candidates' %}
{{candidate.0.birthday}}
{{candidate.1}} <= view内で作成したフィールド
{% endfor %}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/14 12:02

    まさに、それです!!!感激です!
    ありがとうございます!活用させていただきます!

    キャンセル

0

Person モデルに判定用の関数を定義するのが良いのではないでしょうか。

class Person(models.Model):

    OPEN_CLOSE = (
        ('1', _('非公開')),
        ('2', _('公開')),
    )
    user = CharField('ユーザー名', max_length=120, null=True)
    birthday = models.DateField(_('生年月日'))
    apply_company = models.ForeignKey('Company',verbose_name=_('応募先'),on_delete=models.CASCADE,null=True,blank=True)画'),blank=True,null=True)
    send_to_company = CharField(_('履歴書公開許可'),choices=OPEN_CLOSE,default='1',blank=True,max_length=30)

    def __str__(self):
        return self.user

    def add_message(self):
        """ここで条件によって返すメッセージを変える"""


HTML 側は e.senaha さんが書いている HTML で呼び出しが可能かと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/14 13:54

    確かにそのやり方もありですね!
    今回は、tatamyiwathyさんのやり方がシンプルそうなのでそちらで対応してみます!
    他の場面でモデル内判定も必要になりそうなので参考にさせていただきます。
    ありがとうございました!

    キャンセル

  • 2020/01/14 14:57

    一応モデルで定義するのとビューで定義することの違いを述べておくと、
    ビューで定義した場合は
    candidates
    のリストを2周しているため、その分の時間がかかります(HTML 内でもforが存在するため)。
    モデルで定義した場合はインスタンス生成時に add_message の関数も作るため、その分のメモリと時間はかかります。
    どちらの方が速いかはちょっと比較できていないためわかりませんが、おそらくスピード的にはモデルで定義した方が速いです(candidates の件数にもよるかもしれません)。
    とは言え、作られているクラウド運用だと思いますし、件数が少なければ誤差レベルだと思うので、あまり気にしなくてもいいかもしれません。

    キャンセル

  • 2020/01/14 18:02

    なるほどですね!勉強になります!
    ちなみに、テンプレート上で条件分岐するのは読み込みに時間がかかるという私の認識はあってますか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る