UserCreationForm
username
과 password
로 새로운 user를 생성하는 ModelFormusername
, password1
, password2
를 가짐# accounts/urls.py
urlpatterns = [
...
path("signup/", views.signup, name="signup"),
...
]
# accounts/views.py
from django.contrib.auth.forms import UserCreationForm
@require_http_methods(["GET", "POST"])
def signup(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save() # 새로운 유저 회원가입 정보 저장
auth_login(request, user) # 회원가입과 동시에 새 회원 정보로 로그인
return redirect("articles:index")
else:
form = UserCreationForm()
context = {"form": form}
return render(request, "accounts/signup.html", context)
<!-- accounts/signup.html -->
<h1>Sign up</h1>
<form action="{% url 'accounts:signup' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
<!-- base.html -->
...
{% else %}
<a href="{% url 'accounts:login' %}"><button>Login</button></a>
<a href="{% url 'accounts:signup' %}"><button>Sign Up</button></a>
{% endif %}
...
# accounts/urls.py
urlpatterns = [
...
path("delete/", views.delete, name="delete"),
...
]
# accounts/views.py
@require_POST
def delete(request):
if request.user.is_authenticated:
request.user.delete() # 회원 탈퇴
auth_logout(request) # 세션 지우기
return redirect("articles:index")
<!-- base.html -->
{% if request.user.is_authenticated %}
...
<form action="{% url 'accounts:delete' %}" method="POST">
{% csrf_token %}
<input type="submit" value="Drop out"></input>
</form>
{% else %}
UserChangeForm
UserChangeForm
을 사용하면 user가 수정하면 안될 정보까지 보임UserChangeForm
의 필요한 기능만 Form 커스텀CustomUserChangeForm
get_user_model()
- 현재 프로젝트에서 활성화 되어있는 유저모델을 반환
- 직접 User 모델을 import 할 수 있지만 get_user_model
을 사용하기를 권장
- Django는 다중 User 모델을 지원하므로 확장에 용이
- 프로젝트의 유연성과 확장성을 높여줌
Class Meta의 fields에 들어갈 수 있는 값들: fields
# accounts/urls.py
urlpatterns = [
...
path("update/", views.update, name="update"),
...
]
# accounts/forms.py
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth import get_user_model
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model() # 현재 프로젝트에서 활성화 되어있는 유저를 반환
fields = [
"first_name",
"last_name",
"email",
]
# accounts/views.py
from .forms import CustomUserChangeForm
@require_http_methods(["GET", "POST"])
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>Update Account</h1>
<form action="{% url 'accounts:update' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Update</button>
</form>
<!-- base.html -->
{% if request.user.is_authenticated %}
...
<a href="{% url 'accounts:update' %}"><button>User Update</button></a>
...
{% else %}
PasswordChangeForm
UserChangeForm
을 보면, 비밀번호를 수정하는 경로를 미리 적어둠CustomUserChangeForm
에서 Overridingupdate_session_auth_hash()
함수를 사용해 로그인 상태를 유지# accounts/urls.py
urlpatterns = [
...
path("password/", views.change_password, name="change_password"),
...
]
# accounts/forms.py
from django.urls import reverse
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model() # 현재 프로젝트에서 활성화 되어있는 유저를 반환
fields = [
"first_name",
"last_name",
"email",
]
# 비밀번호 수정 경로를 커스텀 할 수 있도록 UserChangeForm의 __init__을 Overriding
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.fields.get("password"):
# reverse: url_name으로부터 url을 찾아가는 함수
password_help_text = (
"You can change the password " '<a href="{}">here</a>.'
).format(f"{reverse('accounts:change_password')}")
self.fields["password"].help_text = password_help_text
# accounts/views.py
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import (
AuthenticationForm,
UserCreationForm,
PasswordChangeForm,
)
@login_required
@require_http_methods(["GET", "POST"])
def change_password(request):
if request.method == "POST":
form = PasswordChangeForm(request.user, 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)
<!-- accounts/change_password.html -->
<h1>Change Password</h1>
<form action="{% url 'accounts:change_password' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Change Password</button>
</form>