[django] UpdateView & UserCreationForm 프로필정보 변경

Hyeseong·2020년 12월 12일
2

django

목록 보기
4/35
post-thumbnail

목적

로그인 이후 사용자가 자신의 프로필 정보를 변경 하고자 할 경우의 기능을 구현하고자 합니다.


준비물

  • UpdateView
  • UserCreationForm

View

사실 회원가입 View로직과 프로필 정보 변경 View로직은 크게 다른 부분이 없습니다. post방식으로 진행되며, 거의 동일한 태그들을 이용하여 해당 값을 입력하고 db에 값을 저장하는 방식인거조.


from accountapp.forms import AccountUpdateForm # forms.py 파일을 만들 거에요.


# 생략

class AccountUpdateView(UpdateView):
    model = User # 기존 AccountCreateView와 동일한 모델 값을 사용해요.
    form_class = AccountUpdateForm # form을 만들어 값을 전달하게 되요. 
    success_url = reverse_lazy('accountapp:hello_world') # 성공적으로 프로필이 완성되면 메인화면으로 넘겨줍니다.
    template_name = 'accountapp/update.html' # template경로 값을 지정해줘요.
    

Routing(url mapping)

주목할 만한 점은 <int:pk> url패턴이 update url 뒤에 있어서 해당 로그인한 유저의 고유한 primary key를 기준으로 정보를 db에서 가져오게 만들어요. 그리고 2번째 인자로 AccountUpdateView를 호출 하게됩니다.

from accountapp.views import hello_world, AccountCreateView, AccountDetailView, AccountUpdateView


urlpatterns = [
	# 생략
    path('update/<int:pk>/', AccountUpdateView.as_view(), name='update'),
]

Template(update.html)

여기 html은 create.html과 사실상 거의 동일해요.
h4태그 텍스트만 바꿔주면 될 것 같아요.

아! key point로 form태그의 action 속성의 값에 pk=user.pk를 적어 주셔야해요.
이전 url에서 받아온 <int:pk>가 방금 적은 값으로 할당되게 되요.

{% extends 'base.html' %}
{% load bootstrap4 %}

{% block content %}
<div style="text-align: center; max-width: 500px; margin: 4rem auto">
    <div class="mb-4">
        <h4>Update Profile</h4>
    </div>

	<form action="{% url 'accountapp:update' pk=user.pk %}" method="post">
        {% csrf_token %}
            {% bootstrap_form form %}
        <input type="submit" class="btn btn-dark rounded-pill col-6 mt-5">
    </form>
</div>

{% endblock %}

Template - 1 (datail.html)

앞서서 update.html 개인 프로필 변경 화면이라면 그 화면에는 어떻게 진입할까요? 통상 개인정보 프로필에서 변경이라는 버튼을 클릭하고 개인 프로필 변경화면으로 진행되지 않겠어요?

그래서 그 진입을 위한 Update Profile 버튼을 만들어 볼게요.

{% if target_user == user %} 이게 핵심이에요!
target_user는 현재 로그인한 유저 객체를 말하고 그냥 user는 서버가 db에서 끌어다온 user 정보를 말해요.

쉽게 말해서 아래 그림처럼 minwoo1이 로그인했는데 admin 계정 화면에 접근해서 계정정보를 변경하지 못하게 하려고 if문을 작성한거에요.

{% extends 'base.html' %}

{% block content %}

    <div>
	    <div style="text-align: center; max-width: 500px; margin: 4rem auto;">
	    	<p>
                {{target_user.date_joined}}
            </p>
	    	<h2 style="font-family: 'NanumSquareB'">
                {{target_user.username}}
            </h2>

            {% if target_user == user %}
            <a href="{% url 'accountapp:update' pk=user.pk %}">
                <p>Update Profile</p>
            </a>
            {% endif %}
	    </div>
</div>


{% endblock %}

Update Profile 화면

아이디는 통상적으로 유저가 마음대로 바꾸게 하지 않아요. 서버관리자나 운영자의 입장에서 매우 까다로운 일들이 발생하기 때문이조.

만약 쇼핑몰에서 물건을 주문하고 그날 저녘 아이디를 바꾸고 다음날 환불을 시도한다면??
쉽게 말해 주민번호 함부러 바꾸게 하지 못하는것과 일맥상통해요.

그러기 위해선 username 부분을 서버쪽에서 비활성화 해주는 로직을 만들건데요.

forms.py

이 파일을 만들어 줘야 해요.

AccountUpdateForm 클래스를 만들어주고 UserCreationForm 을 상속받아요.

이후 생성자로 인자 3개를 넣어두고 super()메소드로 부모 클래스의 변수들을 호출합니다?!
다음 기존 정의된 username 키값을 disabled로 설정해주는데 이때 True로 해당 값을 지정해주면 끝입니다.

그럼 위의 사진처럼 id 부분이 비활성화 되어 입력할 수없게 되는거조.

from django.contrib.auth.forms import UserCreationForm

class AccountUpdateForm(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['username'].disabled = True
profile
어제보다 오늘 그리고 오늘 보다 내일...

1개의 댓글

comment-user-thumbnail
2023년 4월 27일

안녕하세요... 글 보다가 따라 해보고 있는데 업데이트 부분에서 아이디를 안 건들고 비밀번호만 바꾸고자 하는데 아이디가 있다면서 변경이 안되네요... 혹시 위 글에서 고쳐할 부분이 따로 있나요?

답글 달기