ユーニックス総合研究所

  • home
  • archives
  • django-form-init-val

DjangoのFormの初期値の設定方法: initial属性の使い方

  • 作成日: 2021-08-24
  • 更新日: 2023-12-26
  • カテゴリ: Django

DjangoのFormの初期値の設定方法

Djangoではフォームを使ってユーザーからの情報を便利に扱うことができます。
フォームの各フィールドには初期値を設定することができます。

この記事ではDjangoのフォーム(Form)のフィールドに初期値を設定する方法を解説します。
結論から言うと初期値の設定にはフォームやフィールドの属性initialを使います。
具体的には↓を見ていきます。

  • 前提とするプロジェクト、アプリ
  • Formのコンストラクタに初期値を渡す方法
  • Formの各フィールドに初期値を設定する方法
  • Formの__init__()内で初期値を設定する方法

関連記事
DjangoのFormの値の取得方法: is_validとcleaned_data
Djangoのフォーム(forms.Form)の使い方【Python】
Djangoのformの今どきな作り方【Python, モデルフォーム】

前提とするプロジェクト、アプリ

今回は解説用にmysiteというプロジェクトと、myappというアプリを作ってます。
フォームについては初期値の設定と表示に焦点を当ててコードを書いてますので、改造してPOSTも処理できるコードに変更するなどしてみてください。

またmysite/urls.pyは↓のようになっています。

# mysite/urls.py  
from django.contrib import admin  
from django.urls import path  
from myapp import views  


urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('user/', views.user, name='user'),  
    path('book/', views.book, name='book'),  
    path('post/', views.post, name='post'),  
]  

Formのコンストラクタに初期値を渡す方法

Formのコンストラクタに初期値を渡す方法です。
前提とするフォームは↓になります。

from django import forms  


class UserForm(forms.Form):  
    "ユーザーの情報を扱うフォーム"  
    name = forms.CharField(label='名前', max_length=64)  
    age = forms.IntegerField(label='年齢')  
    weight = forms.FloatField(label='体重')  
    height = forms.FloatField(label='身長')  
    registed = forms.DateTimeField(label='登録日')  
    single = forms.BooleanField(label='独身')  

このフォームはユーザーの情報を扱うフォームです。
名前や年齢などのフィールドがあります。

このフォームをオブジェクト(インスタンス)にするにはコンストラクタを呼ぶわけですが、その時にinitital引数に初期値のデータを渡すことでフォームの各フィールドに初期値を設定することが出来ます。

from django.shortcuts import render  
from django.utils import timezone  
from django.http import HttpResponse  
from myapp.forms import UserForm  


def user(request):  
    if request.method == 'GET':  
        # フォームを規定値で初期化  
        form = UserForm(initial={  
            'name': '匿名',  
            'age': 20,  
            'weight': 50.3,  
            'height': 175.2,  
            'registed': timezone.now(),  
            'single': True,  
        })  

        context = { 'form': form }  # コンテキストにフォームを納格  
        return render(request, 'myapp/user.html', context)  # 描画  
    else:  
        return HttpResponse('未実装')  

↑のようにビューの中でUserFormをオブジェクト(form)にします。
その時にコンストラクタのinitial引数に初期値を渡します。
初期値を設定したフォームはそのままコンテキスト(context)に保存します。
そしてそのコンテキストを使ってテンプレートファイル(myapp/user.html)を描画すれば、初期値を設定したフォームを描画することが可能です。

描画するテンプレートファイルの内容は↓のようになります。

{# myapp/templates/myapp/user.html #}  

<h1>ユーザー登録フォーム</h1>  

<form action="{% url 'user' %}" method="POST">  
  {% csrf_token %}  
  {{ form.as_p }}  
  <input type="submit" value="登録" />  
</form>  

↑のテンプレートファイルを描画すると↓のような画面になります。

Formの各フィールドに初期値を設定する方法

フォームを定義するときに各フィールドのコンストラクタの引数initialに初期値を渡しておくと、そのフィールドをその初期値で初期化(表示上の)しておくことが可能です。

# myapp/forms.py  
from django import forms  
from django.utils import timezone  


class BookForm(forms.Form):  
    "本の情報を扱うフォーム"  
    title = forms.CharField(label='タイトル', max_length=64, initial='無題')  
    price = forms.IntegerField(label='価格(円)', initial=2000)  
    published = forms.DateTimeField(label='出版日', initial=timezone.now())  

↑の場合、titleという本の名前を表現する属性にはinitialに文字列「無題」を渡しています。
こうするとtitleフィールドをその値で初期化することが出来ます。
同様にpricepublishedなどのフィールドも同じように初期値を設定します。

このBookFormは↓のような感じでビューで描画します。

# myapp/views.py  
from django.shortcuts import render  
from django.http import HttpResponse  
from myapp.forms import BookForm  


def book(request):  
    if request.method == 'GET':  
        form = BookForm()  # フォームの作成  
        context = { 'form': form }  # コンテキストにフォームを納格  
        return render(request, 'myapp/book.html', context)  # 描画  
    else:  
        return HttpResponse('未実装')  

テンプレートファイル(myapp/book.html)は↓のような感じになります。

{# myapp/templates/myapp/book.html #}  

<h1>本の登録フォーム</h1>  

<form action="{% url 'book' %}" method="POST">  
  {% csrf_token %}  
  {{ form.as_p }}  
  <input type="submit" value="登録" />  
</form>  

フォームを描画すると↓のような画面になります。

フィールドのinitial引数は公式のソースコード内のコメントでは↓のように説明されています。

initial -- A value to use in this Field's initial display. This value is not used as a fallback if data isn't given.

日本語にすると「値はフィールドの初期表示で使われます。データが与えられていない場合のフォールバックとして値は使われません」という意味になります。

Formの__init__()内で初期値を設定する方法

フォームの__init__()メソッド(コンストラクタ)を上書きして、そのメソッドの中で各フィールドに初期値を設定するには↓のようなコードを書きます。

from django import forms  


class PostForm(forms.Form):  
    "掲示板への投稿情報を扱うフォーム"  
    name = forms.CharField(label='名前')  
    content = forms.CharField(label='内容', widget=forms.Textarea)  

    def __init__(self, *args, **kwargs):  
        super().__init__(*args, **kwargs)  

        self.fields['name'].initial = '匿名'  
        self.fields['content'].initial = '本文なし'  

__init__()の中でself.fields属性にアクセスします。
self.fields[]に参照したいフィールド名を文字列で指定して、そのフィールドのinitial属性に初期値を設定します。
こうすることで各フィールドに初期値を設定することが出来ます。

このフォーム(PostForm)をビューで利用するには↓のようなコードを書きます。

from django.shortcuts import render  
from django.http import HttpResponse  
from myapp.forms import PostForm  


def post(request):  
    if request.method == 'GET':  
        form = PostForm()  # フォームの作成  
        context = { 'form': form }  # コンテキストにフォームを納格  
        return render(request, 'myapp/post.html', context)  # 描画  
    else:  
        return HttpResponse('未実装')  

テンプレートファイル(myapp/post.html)は↓のようにします。

{# myapp/templates/myapp/post.html #}  

<h1>投稿フォーム</h1>  

<form action="{% url 'post' %}" method="POST">  
  {% csrf_token %}  
  {{ form.as_p }}  
  <input type="submit" value="投稿" />  
</form>  

このフォームを描画すると↓のような画面になります。

おわりに

今回はDjangoのフォームの初期値の設定方法について詳しく見てみました。
Djangoのフォームに初期値を設定しておきたいケースはわりと多いかと思います。
initialというキーワードを心のどこかにとどめておいてください。

🦝 < 困ったらinitial

🐭 < initial D (Django)