[Django3.0]ログイン画面の作成およびログイン処理

途中までパラパラ記事を見ながら進めていたが、Django2系とかと同じようにやっても上手く行かなかったので、公式のドキュメントを読みながら進めたいと思います。

Djangoの認証システムを使用する

### forms.py
まず、forms.pyから最初に作ります。AuthenticationFormをimportします。

forms.py

from django.contrib.auth.forms import AuthenticationForm

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

### urls.py
ログイン画面用のパス(login/)とログイン認証処理用(login_auth/)、ログイン後にリダイレクトするパス(/)を用意します。

urls.py

urlpatterns = [
    // 省略
    path('login/', views.login_form, name='login_form'),
    path('login_auth/', views.login_auth, name='login_auth'),
    path('', views.top, name='top'),
    // 省略
]

### views.py
– login画面は、forms.pyで作成したLoginFormを読み込みます。
– ログイン認証処理では、postされたusernameとpasswordからauthenticateして、userが存在すればトップページにリダイレクトさせます。

views.py

from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from .forms import LoginForm

def login_form(request):
	params = {
		'form': LoginForm(),
	}
	return render(request, 'myapp/login.html', params)
	
def login_auth(request):
	username = request.POST['username']
	password = request.POST['password']
	user = authenticate(request, username=username, password=password)
	if user is not None:
		login(request, user)
		return redirect('/')
	else:
		params = {
			'form': LoginForm(request.POST),
		}
		return render(request, 'myapp/login.html', params)

@login_required(login_url='/login/')
def top(request):
	return render(request, 'myapp/top.html')

### template
テストの為、テンプレートは適当に作ってます。※エラーメッセージのところが上手くいってないので、views.py, forms.pyと合わせて修正する必要がある。

<form action="/login_auth/" method="POST">
	{% csrf_token %}
	{{ form.non_field_errors }}
	{% for field in form %}
		{{ field}}
		{{ field.errors }}
	{% endfor %}
	<button type="submit" class="btn btn-success btn-lg btn-block">ログイン</button>
	</form>

ログイン前

ログイン後
-> topページにリダイレクトしました。

続いて、ログアウト処理を作っていきます。