komoto / エンジニアブログ

プログラミングについてアウトプットします。

【django】raise ValidationErrordeで指定したエラーメッセージを表示する

pythonの通常のtry, exceptの例外処理とは違っていて例外検出とその内容の表示に詰まったので、記録に残しておきます。

今回はフォームやモデルでバリエーションチェックする場合に、独自のバリデーションチェックに引っかかったときのエラーメッセージの表示について記事にしたいと思います。

簡単な状況説明

OpenCVを使って簡単なBlur(ぼかし)フィルタ機能を開発していて、ユーザからフィルタサイズを入力してもらって、その値から効果強度(フィルタの大きさ)を決めようと思いました。

そこで、Formクラスを使ってフォームを作りましたが、ガウシアンフィルタを使ったため入力された値が偶数だとエラーがでます。

ここから、Formクラスに「入力された値が偶数ならエラー処理する」という独自のバリエーションチェックを作ろうと考えました。

ソースコード

間違っていたら、ごめんなさい。 models.pyはあまり気にしなくてもいいです。

app_name = 'app'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
]
class Image(models.Model):
    img_src = models.ImageField(upload_to=get_upload_to)   
def is_oddnumber(value): #奇数かどうかをチェックする関数
    if value % 2 == 0:
        raise ValidationError('偶数を入力してください')
class Form(forms.ModelForm):
    class Meta:
        model = Image
        fields = ('img_src')

    filter_size = forms.IntegerField(
        required=True,
        max_value=100,
        min_value=1,
        validators=[is_oddnumber], #追加で上のis_oddnumberでバリデーションチェックを行う
    )
class IndexView(generic.TemplateView)
     
    template_name = index.html
    
    def get(self, request, *args, **kwargs):
        form = Form()
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = Form(request.POST, request.FILES)
        if form.is_valid():
             return redirect(○)
        return render(request, self.template_name, {'form': form}) #エラーメッセージを含んだフォームをセットして再表示
<form action="{% url 'app:index' %}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
</form>

{% if form.errors %}
<ul>
    {% for error in form.non_field_errors %}
    <li>{{ error }}</li>
    {% endfor %}
</ul>
{% endif %}

raise ValidationErrorの引数であるエラーメッセージはform.errorsに格納されるみたいです。

そのため、バリエーションエラーが発生した場合は、エラーメッセージをform.errorsに含んだformをrenderとかで再度表示しなおしてやれば、形としては画面遷移なしにエラーメッセージを表示できます。