DjangoのModleFormとはModelとFormを連携させてデータの挿入・更新をすることができる機能であり、ユーザが画面から入力した値を簡単にDBに保存・更新することができる。
ここでは、基本的なModelFormの使い方について説明する。
フォーム用のクラス(form.py)の作成とビュー・テンプレートの定義
- models.pyに登録するモデルを定義する。
class MyUser(models.Model):
user_name = models.CharField(max_length=128)
age = models.IntegerField()
portfolio_site = models.URLField(blank=True)
- 次に、form.pyをmodels.pyなどと同じ階層に作成してdjango.forms.ModelFormを継承したクラスを作成する。中にMetaクラスを作成して、どのModelに対するフォームなのか定義を記載する
from django import forms
from .models import MyUser
class UserForm(forms.ModelForm): # ModelFormを継承
class Meta():
model = MyUser # どのmodelを利用するかmodel = モデル名で定義
fields = ('user_name', 'age', 'portfolio_site') # 表示するフィールド、'__all__'とすると全て
ちなみに、Metaクラスの中に、exclude=('', )とすると表示しないフィールドを指定できる。
- 次に、views.pyにてこのFormのインスタンスを作成してテンプレートに渡します。テンプレートのファイルの配置はこちらを参照
from . import forms
def form_create_view(request):
form = forms.UserForm()
return render(request, 'app/form_page.html', {'form': form})
- URLマッピングについての設定(URLマッピングについてはこちら)
from app import views
app_name = 'app'
urlpatterns = [
path('form_create_view', views.form_create_view, name='form_create_view'),
]
- 最後に、テンプレートでformを表示します。これには、form.as_pを利用するときれいに表示されます(as_pについては、こちらの記事を参照)。
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <title>Forms</title>
</head>
<body>
<h1>Fill out the form!</h1>
<div class="container">
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
</body>
</html>
以上、formの画面表示については記述した。
- ちなみに画面には以下のように表示される
POSTメソッドで値を渡して、DBにデータを登録する
- formで送信した値を取り出して保存するには、以下のようにsave()メソッドを利用すればよい
from . import forms
def form_create_view(request):
form = forms.UserForm(request.POST or None)
if form.is_valid(): # 値が正しいか確認(バリデーション)
form.save() # 値をDBへの登録
return render(request, 'basicapp/form_page.html', {'form': form})
- 画面から、Formで値を送信した結果DBのMyUserテーブルに値が登録されていることが確認できる
POSTメソッドで値を渡して、DBのデータを更新する
ModelFormを用いてDBの中身を更新したい場合には、formオブジェクト作成時にForm(instance=○○)として、DBの更新対象とするインスタンスを指定する。
以下のようにViewを定義して、実行する。
- viewにデータを更新する処理を追加する
user = get_object_or_404(MyUser, pk=pk) # pkを指定して、DBからレコードを取得する
form = forms.UserForm(request.POST or None, instance=user) # 上でDBから取得したレコードとPOSTリクエストを設定する
if form.is_valid():
form.save() # DBの値を更新
return render(request, 'app/form_update.html', {'form': form})
- テンプレートを表示(app/form_update.html)
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <title>Forms</title>
</head>
<body>
<h1>Fill out the form!</h1>
<div class="container">
<form method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
</body>
</html>
- 画面表示(instance=userで設定したuserの値が初めから設定される)
ModelFormからModelのフィールドから使うフィールドを制限する
ModelFormには、使うフィールドを指定する方法がある。
必要なフィールドだけを表示することで、ユーザーの余分な入力の手間が省けることと、フォームが予期せずセキュリティ上の問題を起こすことを防ぐことができる。
- fieldsを__all__にすることですべてのフィールドを表示する
class UserForm(ModelForm):
class Meta:
model = User
fields = '__all__'
- fieldsにいくつかのフィールドを指定する
class UserForm(ModelForm):
class Meta:
model = User
fields = ['name', 'title', 'birth_date']
- excludeで表示から除外するフィールドを指定する
class UserForm(ModelForm):
class Meta:
model = User
exlude = ['name', 'title', 'birth_date']
以上、ModelFormの利用方法について詳細に記述した。