로그인, 로그아웃, 회원가입, 회원탈퇴 기능을 구현해보자
accounts app 생성하기
urls 분리하기
custom user model 대체하기
# accounts/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
pass
# settings.py
AUTH_USER_MODEL = 'accounts.User' # 기본 값 'auth.User'
# accounts/admin.py
from django.contrib import admin
# Register your models here.
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
session을 create하는 과정
# accounts/urls.py
path('login/', views.login, name='login'),
# accounts/views.py
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login as auth_login
def login(request):
if request.method == 'POST':
form = AuthenticationForm(request, request.POST)
if form.is_valid():
auth_login(request, form.get_user())
return redirect('articles:index')
else:
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'accounts/login.html', context)
# accounts/login.html
<body>
<h1>로그인</h1>
<form action="{% url 'accounts:login' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</body>
session을 delete하는 과정
# accounts/urls.py
path('logout/', views.logout, name='logout'),
# accounts/views.py
def logout(request):
auth_logout(request)
return redirect('articles:index')
# article/index.html
<body>
<form action="{% url 'accounts:logout' %}" method="POST">
{% csrf_token %}
<input type="submit" value="Logout">
</form>
</body>
<h3>안녕하세요, {{ user }} 님!</h3>
User 객체를 create 하는 것
# accounts/urls.py
path('signup/', views.signup, name='signup'),
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
# 현재 우리가 사용하는 User class로 재정의
model = get_user_model()
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
fields = ('email', 'first_name', 'last_name',)
# accounts/views.py
from .forms import CustomUserCreationForm, CustomUserChangeForm
def signup(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
form = CustomUserCreationForm()
context = {
'form': form,
}
return render(request, 'accounts/signup.html', context)
# accounts/views.py
from .forms import CustomUserCreationForm, CustomUserChangeForm
def signup(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request,user)
return redirect('articles:index')
else:
form = CustomUserCreationForm()
context = {
'form': form,
}
return render(request, 'accounts/signup.html', context)
# signup.html
<h1>회원가입</h1>
<form action="{% url 'accounts:signup' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
User 객체를 delete하는 것
# accounts/urls.py
path('delete/', views.delete, name='delete'),
# accounts/views.py
def delete(request):
# print(dir(request.user))
request.user.delete()
return redirect('articles:index')
# index.html
<form action="{% url 'accounts:delete' %}" method="POST">
{% csrf_token %}
<input type="submit" value="회원탈퇴">
</form>
# accounts/urls.py
path('update/', views.update, name='update'),
# accounts/views.py
from .forms import CustomUserCreationForm, CustomUserChangeForm
def update(request):
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
form = CustomUserChangeForm(instance=request.user)
context = {
'form': form,
}
return render(request, 'accounts/update.html', context)
# accounts/update.html
<h1>회원정보 수정</h1>
<form action="{% url 'accounts:update' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
# accounts/urls.py
path('password/', views.change_password, name='change_password'),
# accounts/views.py
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
# 비밀번호 변경시 세션 무효화 방지
update_session_auth_hash(request, user)
return redirect('articles:index')
else:
form = PasswordChangeForm(request.user)
context = {
'form': form,
}
return render(request, 'accounts/change_password.html', context)
# change_password.html
<h1>비밀번호 변경</h1>
<form action="{% url 'accounts:change_password' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
사용자가 인증 되었는지 여부를 알 수 있는 User model의 속성
# article/index.html
{% if request.user.is_authenticated %}
<h3>안녕하세요, {{ user }} 님!</h3>
<form action="{% url 'accounts:logout' %}" method="POST">
{% csrf_token %}
<input type="submit" value="Logout">
</form>
<form action="{% url 'accounts:delete' %}" method="POST">
{% csrf_token %}
<input type="submit" value="회원탈퇴">
</form>
<a href="{% url 'accounts:update' %}">회원정보수정</a>
{% else %}
<a href="{% url 'accounts:login' %}">Login</a>
<a href="{% url 'accounts:signup' %}">Signup</a>
{% endif %}
def login(request):
if request.user.is_authenticated:
return redirect('articles:index')
...
def signup(request):
if request.user.is_authenticated:
return redirect('articles:index')
...
인증된 사용자에 대해서만 view 함수를 실행 시키는 데코레이션
from django.contrib.auth.decorators import login_required
@login_required
def logout(request):
...
@login_required
def update(request):
...