バリデーション - Django

ブラウザのデフォルトのバリデーションの無効化

form 要素に novaldate 属性を設定すると、ブラウザのデフォルトのバリデーション機能を無効にすることができます。models.py で、指定している「 maxlength 」の設定は有効なままです。

フォームに novalidate 属性を付与すると required オプションは無効になります。

<form action="{% url 'create' %}" method="post" novalidate>
  ...
</form>

create にバリデーション機能をつける

pythonApp\crud\crud\member\templates\member\create.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>member/create</title>
</head>
<body>
  <h1>member/create</h1>
  <p>{{message}}</p>
  <table>
    <form action="{% url 'create' %}" method="post" novalidate>
      {% csrf_token %}
      {{ form.as_table }}
      <tr>
        <td></td>
        <td><input type="submit" value="click"></td>
      </tr>
    </form>
  </table>
</body>
</html>

「 views.py 」を次のように変更します。

pythonApp\crud\crud\member\views.py

def create(request):
  params = {
    'title': 'Hello',
    'message': '',
    'form': UserForm(),
  }

  if(request.method == 'POST'):
    obj = User()
    user = UserForm(request.POST, instance=obj)
    params['form'] = user
    
    if (params['form'].is_valid()):
      user.save()
      return redirect(to='/member')
    else:
      params['message'] = "登録できませんでした。"
  
  return render(request, 'member/create.html', params)

モデルで使えるバリデータ

  • MinValueValidator
  • MaxValueValidator
  • MinLengthValidator
  • MaxLengthValidator
  • EmailValidator
  • URLValidator
  • ProhibitNullCharactersValidator
  • RegexValidator

Validator の読み込み、指定方法は次のようにします。

from django.core import validators

name = models.CharField(max_length=100, validators=[validators.MinLengthValidator(5)])
from django.core.validators import MinValueValidator, MaxValueValidator, MinLengthValidator

name = models.CharField(max_length=100, validators=[MinLengthValidator(5)])

モデルで独自のバリデーションを追加するには、次のようにします。

pythonApp\crud\crud\member\models.py

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator, MinLengthValidator, RegexValidator, ValidationError
import re
from datetime import date

# Create your models here.
def future_day(value):
  if value > date.today():
    raise ValidationError("生年月日が未来日です。")
  return value

class User(models.Model):
  name = models.CharField(max_length=100)
  mail = models.EmailField(max_length=200)
  gender = models.BooleanField()
  age = models.IntegerField(default=0)
  birthday = models.DateField(default=date.today, validators=[future_day])

  def __str__(self):
    return ''

バリデーションのエラーメッセージの変更

初期のエラーメッセージを変更したい場合、「 forms.py 」を次のようにします。

pythonApp\crud\crud\member\forms.py

from django import forms
from .models import User

class UserForm(forms.ModelForm):
  class Meta:
    model = User
    fields = ['name', 'mail', 'gender', 'age', 'birthday']

    error_messages = {
      "name": {
        "required": "名前が入力されていません",
      },
      "birthday": {
        "invalid": "入力形式が違います"
      }
    }

エラーメッセージに指定できるキーは、次の表を参考にしてください。

フィールド キー
BooleanField required
CharField required, max_length, min_length
ChoiceField required, invalid_choice
TypedChoiceField required, invalid_choice
DateField required, invalid
DateTimeField required, invalid
DecimalField required, invalid, max_value, min_value, max_digits, max_decimal_places, max_whole_digits
EmailField required, invalid
FileField required, invalid, missing, empty
FilePathField required, invalid_choice
FloatField required, invalid, max_value, min_value
ImageField required, invalid, missing, empty, invalid_image
IntegerField required, invalid, max_value, min_value
IPAddressField required, invalid
MultipleChoiceField required, invalid_choice, invalid_list
NullBooleanField -
RegexField required, invalid
TimeField required, invalid
URLField required, invalid, invalid_link

DateField の日付フォーマットチェックで、「 %Y/%m/%d 」形式で入力した際、バリデーションエラーになる場合、「 settings.py 」を次のように変更します。

pythonApp\crud\crud\crud\settings.py

from django.conf.global_settings import DATETIME_INPUT_FORMATS, DATE_INPUT_FORMATS

DATE_INPUT_FORMATS += ('%Y/%m/%d',)
DATETIME_INPUT_FORMATS += [
    '%Y/%m/%d',
    '%Y/%m/%d %H:%M:%S',
]