ログイン画面(ログイン機能) - Django

バリデーション

pythonApp\auth\auth\hello\templates\hello\login.html

{% extends "hello/base.html" %}
{% block title %}ログイン{% endblock %}

{% block content %}
<div class="container">
  <h1>ログイン</h1>
  <form action="" method="POST" novalidate>
    {% csrf_token %}
    {{ form.non_field_errors }}

    {% for field in form %}
      <div>
        <p>{{ field.label }}<br>{{ field }}</p>
        <div>
          {% for error in field.errors %}
            {{error}}
          {% endfor %}
        </div>
      </div>
    {% endfor %}
    <p><button type="submit">ログイン</button></p>
  </form>
</div>
{% endblock %}

non_field_errors を使うことで clean() メソッドで定義したエラーを取得できます。

単一のフィールドを検証する場合であればclean_xxx()、複数のフィールドにまたがった検証を行うのであればclean()メソッドを用います。

pythonApp\auth\auth\hello\forms.py

from django.contrib.auth.forms import AuthenticationForm
from django import forms
from django.contrib.auth import get_user_model
from django.core.exceptions import ObjectDoesNotExist

class LoginForm(AuthenticationForm):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    for field in self.fields.values():
      field.widget.attrs["class"] = "form-control"

  def clean(self):
    username = self.cleaned_data.get('username')
    password = self.cleaned_data.get('password')

    try:
      user = get_user_model().objects.get(username=username)
    except ObjectDoesNotExist:
      raise forms.ValidationError("正しいユーザー名を入力してください")
    
    if not user.check_password(password):
      raise forms.ValidationError("正しいユーザー名とパスワードを入力してください")

non_field_errors で作成されるデフォルトのエラーメッセージの HTML は以下になります。

<ul class="errorlist nonfield">
  <li>正しいユーザー名とパスワードを入力してください。どちらのフィールドも大文字と小文字は区別されます。</li>
</ul>

get_user_model()

CustomUser モデル、Django デフォルトの User モデルを問わず、使用している User モデルを返してくれる関数

get_user_model を使うことで、views ファイルなどで簡単に user オブジェクトを作ることができます。

objects.get はオブジェクトが存在しないときに DoesNotExist 例外を発生させるが objects.filter はオブジェクトが存在しないときでも DoesNotExist 例外は発生しない。