사용자의
정보 및 권한 변경
위해 admin 인터페이스에서 사용되는 ModelForm
CustomUserChangeForm 사용하기
...
from django.contrib.auth.forms import UserChangeForm
...
class CustomUserChangeFrom(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
from django.urls import path
from . import views
app_name = "accounts"
urlpatterns = [
...
path("update/", views.update, name="update"),
]
...
def update(request):
if request.method == 'POST':
pass
else:
form = CustomUserChangeFrom(instance=request.user)
context = {
'form':form,
}
return render(request, 'accounts/update.html', context)
{% extends 'base.html' %}
{% load django_bootstrap5 %}
{% block body %}
<h1>회원 정보 수정</h1>
<form action="{% url 'accounts:update' %}" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_button button_type='submit' content='OK' %}
</form>
{% endblock body %}
회원정보 수정 url 추가
...
<body>
{% if request.user.is_authenticated %}
<span>{{ request.user }}</span>
<a href="{% url 'accounts:logout' %}">로그아웃</a>
<a href="{% url 'accounts:update' %}">회원정보 수정</a>
{% else %}
<a href="{% url 'accounts:signup' %}">회원가입</a>
<a href="{% url 'accounts:login' %}">로그인</a>
{% endif %}
<div class='container'>
{% block body %}
{% endblock body %}
{% bootstrap_javascript %}
</div>
</body>
세부 항목 전부다 보이므로 원하는 항목만 보이도록 구현
Meta 클래스를 보면 User라는 model을 참조하는 ModelForm이라는 것을 확인할 수 있음
• https://github.com/django/django/blob/main/django/contrib/auth/forms.py#L147
User 클래스 구조 확인
실제로 User 클래스는 Meta 클래스를 제외한 코드가 없고 AbstractUser 클래스를 상속 받고있음
• https://github.com/django/django/blob/main/django/contrib/auth/models.py#L405
AbstractUser 클래스 구조 확인
클래스 변수명들을 확인해보면 회원수정 페이지에서 봤던 필드들과 일치한다는 것을 확인할 수 있음
• https://github.com/django/django/blob/main/django/contrib/auth/models.py#L334
마지막으로 공식문서의 User 모델 Fields 확인
• https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#user-model
class CustomUserChangeFrom(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
fields = ('email', 'first_name', 'last_name',)
def update(request):
if request.method == 'POST':
form = CustomUserChangeFrom(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
...
사용자가 비밀 번호를 변경할 수 있도록 하는 Form
from django.urls import path
from . import views
app_name = "accounts"
urlpatterns = [
...
path('password/', views.change_password, name='change_password'),
]
...
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm
...
def change_password(request):
if request.method == 'POST':
pass
else:
form = PasswordChangeForm(request.user)
context = {
'form':form,
}
return render(request, 'accounts/change_password.html', context)
{% extends 'base.html' %}
{% load django_bootstrap5 %}
{% block body %}
<h1>비밀번호 변경</h1>
<form action="{% url 'accounts:change_password' %}" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_button button_type='submit' content='OK' %}
</form>
{% endblock body %}
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user,request.POST)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
...
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)
비밀번호가 변경되면 기존 세션과의 회원 인증 정보가 일치하지 않게 되어 버려
로그인 상태가 유지되지 못함
from django.contrib.auth import update_session_auth_hash
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
# form = PasswordChangeForm(user=request.user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('articles:index')
else:
form = PasswordChangeForm(request.user)
context = {
'form': form,
}
return render(request, 'accounts/change_password.html', context)
"탈퇴(1) 후 로그아웃(2)"의 순서가 바뀌면 안됨
=> 먼저 로그아웃 해버리면 해당 요청 객체 정보가 없어지기 때문에
=> 탈퇴에 필요한 정보 또한 없어지기 때문
def delete(request):
request.user.delete()
auth_logout(request)