DjangoのForm機能の説明

皆さん、こんにちは。今日はDjangoのFormクラスについて紹介したいと思います。 前回までで説明した事は以下になります。

フォルダの構造は以下の様になっています。

mysite
├── hello
│   ├── admin.py
│   ├── apps.py
│   ├── fixtures
│   │   └── test-data.json
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-36.pyc
│   │       └── __init__.cpython-36.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-36.pyc
│   │   ├── __init__.cpython-36.pyc
│   │   ├── models.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── views.cpython-36.pyc
│   ├── static
│   │   └── css
│   │       ├── bootstrap.min.css
│   │       └── style.css
│   ├── templates
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
└── mysite
    ├── asgi.py
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-36.pyc
    │   ├── settings.cpython-36.pyc
    │   ├── urls.cpython-36.pyc
    │   └── wsgi.cpython-36.pyc
    ├── settings.py
    ├── urls.py
    └── wsgi.py
目次

Formの説明

DjangoにはFormクラスの機能があります。

この機能を使うとhtml内でpythonで作られたフォームを表示する事ができます。

その上、バリデーション機能や他の機能を簡単に実装できるので、

formなどを作る時動く便利です。

今回はFormの引数や表示方法について紹介します。

Formのコアフィールド引数

フォームはこれらの引数をつけられます。 引数はいかになります。

フィールド引数説明
required項目が必要か必要でないかを設定します。TrueかFalseをつけられます。デフォルトではTrueです。なので空白やclean()した場合ValidationErrorがおきます。
label項目にラベルをつけます。ラベルは文字列です。デフォルトの場合アンダースコアを空白、最初の文字を大文字に変換して生成されます。
label_suffixラベルの後の記号です。デフォルトではコロンです。これを設定する事で記号をオーバーライドできます。
initial初期値を設定します。
widgetwidgetをしていします。Widgetの種類はオフィシャルページを見てください。
help_textFieldを説明するテキストです。テンプレートに渡した後、テンプレート内でフォームのフィールド.help_textやフォーム.as_pなどで表示できます。
error_messages辞書型で渡すことで、ValidationErrorが起きた時渡した値となります。
validatorsバリデーション関数の設定。関数の一覧はオフィシャルページを見てください。カスタム(自分で設定)する事もできます。
localizeformデータの入力とレンダリングした出力のローカライゼーションを有効にします。
disabledTrueかFalseをつけられます。Trueの場合フォームの値を編集することはできません。

FormのFieldクラス

DjangoのFieldクラスは以下になります。

フィールドクラス既定のウィジェット説明エラーメッセージキー
BooleanFieldCheckboxInputチェックすることができる。同時にrequired = Trueの時チェックしているかチェックする。required
CharFieldTextInput文字列を入力する事ができる。同時にmax_length、min_lengthがある場合そのバリデーション関数が存在しチェックする。required,max_length,min_length
ChoiceFieldSelectリストから選択する。同時に値がリストに存在するかチェックする。required,invalid_choice
TypedChoiceFieldSelectリストから選択する。同時に値がリストに存在するかチェックする。選択した値の型はcoerceで指定した型になるrequired,invalid_choice
DateFieldDateInput日付のフォーマットを入力することができる。同時にdatetime.date、datetime.datetime又は指定した文字列型のフォーマットかをチェックする。(input_formatsオプションで指定する事ができる)required,invalid
DateTimeFieldDateTimeInput日付のフォーマットを入力することができる。同時にdatetime.date、datetime.datetime又は指定した文字列型のフォーマットかをチェックする。(input_formatsオプションで指定する事ができる)required,invalid
DecimalFieldField.localize=True -->NumberInput それ以外TextInput小数を入力することができる。同時に値がDecimalかチェックする。max_value、min_valueがある場合そのバリデーション関数が存在しチェックする。required,invalid,max_value, min_value,max_digits, max_decimal_places, max_whole_digits
DurationFieldTextInput文字列を入力する。同時にTimedelta型に変換できる文字列かチェックする。値はdatetime.timedelta.minとdatetime.timedelta.maxの合間かをチェックする。required,invalid,overflow
EmailFieldEmailInputメールアドレスを入力する。同時にメールアドレスかチェックする。max_length、min_lengthがある場合そのバリデーション関数が存在しチェックする。required,invalid
FileFieldClearableFileInputファイルをアップロードする。同時にファイルをアップロードしたかチェックする。required,invalid,missing,empty, max_length
FilePathFieldSelectディレクトリを指定しその中のファイル/フォルダを選択できるようにする。required,invalid
FloatFieldField.localize=True -->NumberInput それ以外TextInputFloat型を入力する。同時にmax_value、min_valueがある場合そのバリデーション関数が存在しチェックする。required, invalid, max_value, min_value
ImageFieldClearableFileInputファイルをアップロードする。同時にファイルをアップロードしたかチェックし、ファイルの種類がPillowにサポートされてるかチェックする。required, invalid, empty, missing, invalid_image
IntegerFieldField.localize=True -->NumberInput それ以外TextInput整数を入力することができる。同時にmax_value、min_valueがある場合そのバリデーション関数が存在しチェックする。required, invalid, max_value, min_value
GenericIPAddressFieldTextInputIPv4、IPv6を入力する。同時にIPアドレスが有効なIPアドレスかをチェックする。required,invalid
MultipleChoiceFieldSelectMultipleリストから選択する(上限が一つではない)。同時に値がリストに存在するかチェックする。required, invalid_choice, invalid_list
TypedMultipleChoiceFieldSelectMultipleリストから選択する(上限が一つではない)。同時に値がリストに存在するかチェックする。選択した値の型はcoerceで指定した型になるrequired,invalid_choice
NullBooleanFieldNullBooleanSelect値がTrue,False,Noneになる。
RegexFieldTextInput正規表現の文字列を入力する。同時にRegexValidatorで正規表現をチェックする。required,invalid
SlugFieldTextInput文字、数字、アンダースコア、ハイフンのみを含むことをチェックする。required,invalid
TimeFieldTimeInput時間のフォーマットを入力することができる。同時にdatetime.time又は指定した文字列型のフォーマットかをチェックする。(input_formatsオプションで指定する事ができる)required,invalid
URLFieldURLInputURLを入力する。同時にURLが有効化チェックする。required,invalid
UUIDFieldTextInput文字列を入力することができる。(hex(16進数)として受け取ることができる文字列)required,invalid

Formを表示するための準備

今回Formを表示するテンプレートを新たに作ります。

そして本来の見栄えも変えます。

新しく作るhtmlの名前はcreate.htmlです。

フォームは.as_tableを使ってテーブルの様に表示します。

ではmysite/templates/の中にcreate.htmlをつくります。

そして以下の様に編集します。

{% load static %}
<html>
<head>
  <meta charset=UTF-8>
  <title>Form test</title>
  <link rel=stylesheet href={% static 'css/style.css' %}>
</head>
<body>
  <h1>Please enter forms below</h1>
  <form action = {% url 'index' %} method=POST class='form'>
    {% csrf_token %}
    <table>
        {{ form.as_table }}
    </table>
    <button type=submit>Submit</button>
  </form>
</body>
<html>

index.htmlはデータが渡された時そのデータを表示します。

mysite/templates/index.htmlを以下の様に編集します。

{% load static %}
<html>
<head>
  <meta charset=UTF-8>
  <title>Original Page</title>
  <link rel=stylesheet href={% static 'css/bootstrap.min.css' %}>
  <link rel=stylesheet href={% static 'css/style.css' %}>

</head>
<body>
    <h1>Welcome to the tutorial</h1>
    <div class=go-form>
      <a href = {% url 'forms' %} class = go-form-button>Fill form</a>
    </div>
    {% if data %}
    <table class=table>
        <thead>
            <tr>
                <th scope=col>#</th>
                <th scope=col>Last</th>
                <th scope=col>First</th>
                <th scope=col>Gender</th>
                <th scope=col>Age</th>
                <th scope=col>Occupation</th>
                <th scope=col>Birthday</th>
                <th scope=col>Email</th>
            </tr>
        </thead>
        <tbody>
            <tr>
            <th scope=row>1</th>
                {% for key,value in data.items %}
                    <td>{{value}}</td>
                {% endfor %} 
            </tr>
        </tbody>
    </table>
    {% endif %}
</body>
<html>

補足:{% csrf_token %}はCSRF攻撃を防ぐものです。(簡単にいうとフォームのリクエストをチェックするという意味です。)

そしてmysite/hello/static/css/のstyle.cssも編集します。

以下の様に編集します。

@charset UTF-8;

body{
    margin:0;
    text-align:center;
}

.go-form-button{
    color:black;
}

.form table{
    margin:0 auto;
}

Formの表示方法 Formの表示方法は以下になります。

  1. アプリフォルダの中にforms.pyを作り、その中に項目を記述します。
  2. そのフォームをviews.pyで表示したいテンプレートに渡します。

では実際にフォームを作ってみましょう。

まずmysite/hello/の中にforms.pyを作ります。

そしてformの項目はいかになります。

  • 性別
  • 年齢
  • 職業
  • 誕生日
  • メールアドレス

(後にモデルから継承する時に二つのフォームが違うことが、 分かるように職業をいれています。)

そしてforms.pyを以下の様に編集します。

from django import forms

class SampleForm(forms.Form):
    sex = [
        ('Male','Male'),
        ('Female','Female'),
    ]
    last_name = forms.CharField(label='Last Name')
    first_name = forms.CharField(label='First Name')
    gender = forms.ChoiceField(label='Gender', choices = sex)
    age = forms.IntegerField(label='Age')
    occupation = forms.CharField(label = 'Occupation')
    birthday = forms.DateField(label='Birthday')
    email = forms.EmailField(label='Email')

そしてindex.htmlでフォームのデータを受け取れる様、 views.pyを以下の様に編集します。

from django.shortcuts import render
from .forms import SampleForm

def show_index(request):
    # リクエストがPOSTだったら内容を表示する
    if request.method == 'POST':
        params = {
            Last:request.POST.get('last_name'),
            first:request.POST.get('first_name'),
            gender:request.POST.get('gender'),
            age:request.POST.get('age'),
            occupation:request.POST.get('occupation'),
            birthday:request.POST.get('birthday'),
            email:request.POST.get('email')
        }
        return render(request, 'index.html', {'data':params})
    # POSTじゃなかったら表示する  
    return render(request,'index.html')

def show_forms(request):
    return render(request, 'forms.html',{'form':SampleForm()})

ではurls.pyを以下の様に編集してください。

from django.urls import path
from . import views

urlpatterns = [
    path('',views.show_index, name='index'),
    path('forms',views.show_forms,name='forms')
]

これで準備は整いました。 コマンドをうって確かめてみましょう。

python manage.py runserver 0:8000

そして<ipアドレス>:8000/helloに行くと以下の様になってます。

そしてFill Formをクリックします。するといかになります。

このフォームを完成します。

そしてindex.html画面に戻り以下の様になります。

Formをモデルから継承

方法は以下になります。

  1. modelをインポートします。
  2. ModelFormを使って継承させます。

では実際にやってみます。

mysite/helllo/forms.pyを以下の様に編集します。

from django import forms
from .models import Personinfo

class SampleForm(forms.ModelForm):
    class Meta:
        model = Personinfo
        fields = ['last_name','first_name','gender','age','birthday','email']

そしてmysite/helllo/views.pyのOccupationを削除します。

コードは以下になります。

from django.shortcuts import render
from .forms import SampleForm

def show_index(request):
    # リクエストがPOSTだったら内容を表示する
    if request.method == 'POST':
        params = {
            Last:request.POST.get('last_name'),
            first:request.POST.get('first_name'),
            gender:request.POST.get('gender'),
            age:request.POST.get('age'),
            birthday:request.POST.get('birthday'),
            email:request.POST.get('email')
        }
        return render(request, 'index.html', {'data':params})
    # POSTじゃなかったら表示する
    return render(request,'index.html')

def show_forms(request):
    return render(request, 'forms.html',{'form':SampleForm()})

最後にindex.htmlのOccupationを削除して完成です。

{% load static %}
<html>
<head>
  <meta charset=UTF-8>
  <title>Original Page</title>
  <link rel=stylesheet href={% static 'css/bootstrap.min.css' %}>
  <link rel=stylesheet href={% static 'css/style.css' %}>

</head>
<body>
    <h1>Welcome to the tutorial</h1>
    <div class=go-form>
      <a href = {% url 'forms' %} class = go-form-button>Fill form</a>
    </div>
    {% if data %}
    <table class=table>
        <thead>
            <tr>
                <th scope=col>#</th>
                <th scope=col>Last</th>
                <th scope=col>First</th>
                <th scope=col>Gender</th>
                <th scope=col>Age</th>
                <th scope=col>Birthday</th>
                <th scope=col>Email</th>
            </tr>
        </thead>
        <tbody>
            <tr>
            <th scope=row>1</th>
                {% for key,value in data.items %}
                    <td>{{value}}</td>
                {% endfor %} 
            </tr>
        </tbody>
    </table>
    {% endif %}
</body>
<html>

これで準備完了です。 コマンドをうって確かめてみましょう。

python manage.py runserver 0:8000

そして<ipアドレス>:8000/helloに行くと以下の様になってます。

そしてFill Formをクリックします。するといかになります。

このフォームを完成します。

そしてindex.html画面に戻り以下の様になります。

次回はこのフォームを使ってデータベースに入れる方法を、紹介します。

よかったらシェアしてね!
  • URLをコピーしました!
目次