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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

446閲覧

djangoのforms.Formを用いたtemplateの書き方について

makun1010

総合スコア59

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2022/09/04 04:38

前提

djangoを用いてwebアプリの開発をしています。

実現したいこと

サンプルコードをもとにして問い合わせフォームを作っているのですが、テンプレートのHTMLのコードで理解できないところがあります。

発生している問題・エラーメッセージ

エラーはありません。このコードで起動すると問題ありません。しかしinquiry.html内の{% for field in form %}のform 、"{{ field.id_for_label}}"、{{ field.label_tag }、{{field}}がなぜforms.pyのクラスInquiryForm(forms.Form)の内容を示せているかがわかりません。formでなぜこのクラスの内容を示せるのでしょうか?そして.id_for_label、.label_tagはどこからきているのですか?

該当のソースコード

pyhton

1inquiry.html---------------------------------------------------- 2{% extends 'base.html'%} 3{% block title%} 4Antt Private Điary 5{% endblock %} 6{% block active_inquiry %}active{% endblock %} 7{% block contents%} 8<div class="container"> 9 <div class="my-div-style"> 10 <form method="post"> 11 {% csrf_token %} 12 {{ form.non_field_errors }} 13 {% for field in form %} 14 <div class="mb-4 col-8"> 15 <label for="{{ field.id_for_label}}" class="form-label"> 16 <strong>{{ field.label_tag }}</strong> 17 </label>{{field}} 18 {{ field.errors }} 19 </div> {% endfor %} 20 <button class="btn btn-primary" type="submit">1. 21 </button> 22 </form> 23 </div> 24</div> 25{% endblock%} 26forms.py------------------------------------------------------------------------- 27from django import forms 28from django.core.mail import EmailMessage 29class InquiryForm(forms.Form): 30 name = forms.CharField(label='お名前', max_length=30) 31 email = forms.EmailField(label='メールアドレス') 32 title = forms.CharField(label='タイトル', max_length=30) 33 message = forms.CharField(label='メッセージ',widget=forms.Textarea) 34 35 def __init__(self, *args, **kwargs): 36 super().__init__(*args, **kwargs) 37 self.fields['name'].widget.attrs['class'] = 'form-control' 38 self.fields['name'].widget.attrs['placeholder'] = 'お名前をここに入力してください。' 39 self.fields['email'].widget.attrs['class'] = 'formcontrol' 40 self.fields['email'].widget.attrs['placeholder'] = 'メールアドレスをここに入力してください。' 41 self.fields['title'].widget.attrs['class'] = 'formcontrol' 42 self.fields['title'].widget.attrs['placeholder'] = 'タイトルをここに入力してください。' 43 self.fields['message'].widget.attrs['class'] = 'form-control' 44 self.fields['message'].widget.attrs['placeholder'] = 'メッセージをここに入力してください' 45views.py-------------------------------------------------------------------------------------------------- 46from django.shortcuts import render 47import logging 48# Create your views here. 49from django.urls import reverse_lazy 50from django.views import generic 51from.forms import InquiryForm 52 53class IndexView(generic.TemplateView): 54 template_name="index.html" 55 56logger=logging.getLogger(__name__) 57class InquiryView(generic.FormView): 58 template_name="inquiry.html" 59 form_class = InquiryForm 60 61 62### 試したこと 63 64 65 66### 補足情報(FW/ツールのバージョンなど) 67 68

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Djangoのforms.Formクラスにはすでにフォームをhtmlにレンダリングするために、すでに定義された変数がいくつかコンテキスト変数に用意されています
なので自分で定義していない変数が多く存在します
こういったのはほぼすべてのクラスビューにあるので公式サイトで確認するのが良いです

まるごとレンダリング

django公式サイトから

html

1<form action="/your-name/" method="post"> 2 {% csrf_token %} 3 {{ form }} 4 <input type="submit" value="Submit"> 5</form>

 上のようにform変数もforms.Formクラスにあるもので、こうするとまるごと入力フォームが差し込まれます
動作的にはクラス内で定義したフィールドに合わせてidなどが設定されたinputなどのタグが差し込まれています

手作業でレンダリング

 この入力フィールドは丸々入ってしまうので、結構ダサい感じになります…。なのでかっこよくした自作の入力フィールドなどから入力フォームを作るための各入力フィールドのid,labelなどがすでに変数でいくつか定義してあります。これらをformがリストとして持っているのでforで回しながら手作業でレンダリングすることが可能です。

django公式サイトから

html

1{% for field in form %} 2 <div class="fieldWrapper"> 3 {{ field.errors }} 4 {{ field.label_tag }} {{ field }} 5 {% if field.help_text %} 6 <p class="help">{{ field.help_text|safe }}</p> 7 {% endif %} 8 </div> 9{% endfor %}

コードに出てきた変数

  • form:全フィールド持ったリスト。そのまま表示すると自動生成された入力フォームが挿入される。
  • field:フィールドの情報変数。そのまま表示すると自動生成されたフィールド入力のinputタグが挿入される。
  • id_for_label:labelタグのfor要素に使うid名
  • label_tag:ラベルを自動生成したタグで挿入

解説

python

1 {% for field in form %} 2 <div class="mb-4 col-8"> 3 <label for="{{ field.id_for_label}}" class="form-label"> 4 <strong>{{ field.label_tag }}</strong> 5 </label>{{field}} 6 {{ field.errors }} 7 </div> {% endfor %}

なので上のコードはlabelにstrongタグを付けたいということでformをfor文で回しているんだと思います
ちなみに個人的にfield.label_tagはfield.labelでいい気がします

詳細は公式にあります(英語なんですが…)
https://docs.djangoproject.com/en/4.1/topics/forms/#rendering-fields-manually
わかりにくい説明かもしれなかったのでここを見ると理解できるかもしれません

投稿2022/09/04 08:25

編集2022/09/04 08:31
rykss

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

makun1010

2022/09/04 09:48

とても分かりやすい説明ありがとうございました!ここでずっと躓いていたので本当に助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問