회원정보 수정

Hvvany·2022년 10월 13일
0

django

목록 보기
5/10

UserChangeForm

사용자의 정보 및 권한 변경위해 admin 인터페이스에서 사용되는 ModelForm
CustomUserChangeForm 사용하기

forms.py

...
from django.contrib.auth.forms import UserChangeForm

...
class CustomUserChangeFrom(UserChangeForm):

  class Meta(UserChangeForm.Meta):
    model = get_user_model()

urls.py

from django.urls import path
from . import views

app_name = "accounts"

urlpatterns = [
    ...
    path("update/", views.update, name="update"),
]

views.py

...
def update(request):
    if request.method == 'POST':
        pass
    else:
        form = CustomUserChangeFrom(instance=request.user)
    
    context = {
        'form':form,
    }
    return render(request, 'accounts/update.html', context)

update.html

{% 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 %}

base.html

회원정보 수정 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>

CustomUserChangeForm fields 재정의

세부 항목 전부다 보이므로 원하는 항목만 보이도록 구현

UserModel 상속 구조

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

forms.py

class CustomUserChangeFrom(UserChangeForm):

  class Meta(UserChangeForm.Meta):
    model = get_user_model()
    fields = ('email', 'first_name', 'last_name',)

views.py

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:
        ...

비밀번호 변경

PasswordChangeForm

사용자가 비밀 번호를 변경할 수 있도록 하는 Form

urls.py

from django.urls import path
from . import views

app_name = "accounts"

urlpatterns = [
    ...
    path('password/', views.change_password, name='change_password'),
]

views.py

...
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)

change_password.html

{% 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 %}

views.py

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:
        ...

참고

회원가입 이후 로그인

views.py

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)"의 순서가 바뀌면 안됨
=> 먼저 로그아웃 해버리면 해당 요청 객체 정보가 없어지기 때문에
=> 탈퇴에 필요한 정보 또한 없어지기 때문

views.py

def delete(request):
	request.user.delete()
	auth_logout(request)
profile
Just Do It

0개의 댓글