【clean】djangoでフォームを複数のカラムにまたがって入力チェックする
【clean】djangoでフォームを複数のカラムにまたがって入力チェックする
参考:
・Djangoのforms.pyでメソッドを使ったフォームのバリデーション
・Django、フォームの表示方法まとめ
挙動
挙動は下の通りです。タイトルとテキストの組み合わせが重複しているとエラーが出て登録を出来ないようにしています。
プログラム
【ルーティング】
# 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
【フォーム】
肝になるのはここだけですね。cleanメソッドで入力値が既に登録済みであるかチェックしています。登録済みであればエラーを発生させます。
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from django import forms
from .models import Blog
class BlogForm(forms.Form):
title = forms.CharField(
label='タイトル',
required=True,
max_length=150,
)
text = forms.CharField(
label='テキスト',
required=True,
max_length=500,
widget=forms.Textarea,
)
def clean(self):
title = self.cleaned_data['title']
text = self.cleaned_data['text']
blog = Blog.objects.filter(
title=title,
text=text,
).exists()
if blog:
raise ValidationError('入力したタイトルとテキストの組み合わせは既に登録済みです。')
【ビュー】
# 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文で回して取り出し表示しています。
<!--templates/myapp/blog_form.html-->
<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.non_field_errors %}
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
{% endif %}
ディスカッション
コメント一覧
まだ、コメントがありません