【validators】djangoでformの入力チェックをしてみる

2021年2月7日

【validators】djangoでformの入力チェックをしてみる

フォームの入力チェックをしてメッセージを表示するところまでメモを残しておきたいと思います。

参考:
  ・Django バリデーション設定の基本 [validation]
  ・【django】raise ValidationErrorで指定したエラーメッセージを表示する

挙動

挙動は下の通りです。タイトルが「hello」の時だけエラーメッセージが出ると言う、あり得ない仕様です。

プログラム

【ルーティング】


# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/', include('myapp.urls')),
]

# myapp/urls.py
from django.urls import path
from . import views

app_name = 'myapp'
urlpatterns = [
    path('blog_form/', views.blog_form, name='blog_form'),
]

【モデル】


# myapp/models.py
from django.db import models

class Blog(models.Model):
    title = models.CharField(blank=False, null=False, max_length=150)
    text  = models.TextField(blank=True)
    created_datetime = models.DateTimeField(auto_now_add=True)
    updated_datetime = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

【フォーム】
肝になるのはここだけですね。validators=[check_title]を指定してあげる事でdef check_titleが呼ばれます。引数のvalueにはタイトルフォームの入力値が入ってきます。


# myapp/forms.py
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from django import forms
from .models import Blog

def check_title(value):
    if value == 'hello':
        raise ValidationError('helloってタイトルだけは止めてください')

def check_text(value):
    if value == 'world':
        raise ValidationError('worldってテキストだけは止めてめてください')

class BlogForm(forms.Form):
    title = forms.CharField(
        label='タイトル',
        required=True,
        max_length=150,
        validators=[check_title],
    )
    text = forms.CharField(
        label='テキスト',
        required=True,
        max_length=500,
        widget=forms.Textarea,
        validators=[check_text],
    )

【ビュー】


# myapp/views.py
from django.shortcuts import render
from myapp.models import Blog
from myapp.forms import BlogForm

def blog_form(request):
    form = BlogForm
    if request.method == 'POST':
        form = BlogForm(request.POST)
        if form.is_valid():
            blog = Blog.objects.create(
                title=form.cleaned_data['title'],
                text=form.cleaned_data['text'],
            )
    context = {
        'form': form
    } 
    return render(request, 'myapp/blog_form.html', context)

【テンプレート】
発生したエラーをfor文で回し表示しています。


<form action="{% url 'myapp:blog_form' %}" method="POST">{% csrf_token %}
    <div>title:</div>
    <dv>{{ form.title }}</div>
    <br>
    <div>text:</div>
    <div>{{ form.text }}</div>
    <br>
    <button type="submit">save</button>
</form>
{% if form.errors.title %}
    {% for error in form.errors.title %}
        <div>{{ error }}</div>
    {% endfor %}
    {% for error in form.errors.text %}
        <div>{{ error }}</div>
    {% endfor %}
{% endif %}

2021年2月7日