LoginSignup
7
8

More than 3 years have passed since last update.

【Django】FormクラスとModelFormクラス

Last updated at Posted at 2019-07-12

Form

Form

from django import forms
from django.core.validators import RegexValidator


class UserForm(forms.Form) :
    CHOICE = (
    ('DB値', '任意'),
    ...
)
    account_id_regex = RegexValidator(regex=r'^[a-zA-Z0-9_@]+$', message='This format is not allowed.')

    select = forms.ChoiceField(label='...', widget=forms.Select, choices=CHOICE)
    volume = forms.DecimalField(label='...', max_digits=7, decimal_places=2)
    account_id = forms.CharField(label='...', validators=[account_id_regex])

    def __str__(self) : 
        return self.account_id

Fieldクラスを使って入力フィールドを定義することで簡単にバリデーションを実装できます。

ModelFormのようにデータベースをオブジェクトとしてバリデーションに引っ掛ける機能を実装したい場合は、ORMが提供しているQuerySet APIを使ってデータベースのレコードを取得し、View側で条件分岐などを駆使してバリデートします。

views.py
from .models import User
from .forms import UserForm
...
def transfer(request) :
    params = {
        'message' : '',
        'form' : UserForm(),
    }
    if (request.method == 'POST') :      
        ...
        if (form.is_valid()) :

            if User.objects.all().filter(account_id=account_id):
...
    return render(request, 'transfer.html', params)

ここでは、QuerySetのallメソッドとfilterメソッドを使って、レコードをモデルのインスタンスとして全件取得した後、入力値とデータベースの完全一致検索をおこなっています。

このようにDjangoは、データベースに格納されているレコードをORMを使ってオブジェクトとして扱えるので便利です。

ちなみにDjangoはRailsと同じActive Recordパターンを採用したORMを使用しています。

ModelForm

ModelForm
from django import forms
from django.core.validators import MaxValueValidator, MinValueValidator
from .models import User
from django.core.validators import RegexValidator


class UserForm(forms.ModelForm) :
    CHOICE = (
    ('DB値', '任意'),
    ...
)

    account_id_regex = RegexValidator(regex=r'^[a-zA-Z0-9_@]+$', message='This format is not allowed.')

    select = forms.ChoiceField(label='...', widget=forms.Select, choices=CHOICE)
    volume = forms.DecimalField(label='...', max_digits=7, decimal_places=2)

    class Meta : 
         model = User
         fields = ['account_id']

    def __str__(self) : 
        return self.account_id

models.py
from django.db import models
from django.forms import ModelForm
from django.core.validators import RegexValidator

class User(models.Model):
    account_id = models.CharField(max_length=50)
    # ...その他フィールド定義

ModelFormの場合、モデルのメタデータをMetaクラスにデータベースアクセスに関連する情報や機能を入れることができます。Metaクラスにexclude属性やfield属性を設定することで、指定したフィールドのフォームを生成したり弾いたりすることができます。
ここでは、selectフィールドとvolumeフィールドをUserFormクラスで定義して、account_idフィールドはデータベース(Model)から引っ張ってきているイメージです。

ただ、同一テーブルから複数のレコードを検索したい場合、どうやってModelFormを使ってバリデーションを組めばいいかわからないので、これからもっと色々試していこうと思います。

また、何かご指摘や質問等あればコメントしていただけると助かります、、!

参照

モデルからフォームを生成する - Django v1.0 documentation

7
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8