관리 메뉴

Storage Gonie

50. (app3) Django 프로필 업데이트 페이지 만들기 본문

웹개발/Django 웹서비스 개발(인프런)

50. (app3) Django 프로필 업데이트 페이지 만들기

Storage Gonie 2019. 2. 28. 20:26
반응형

1. forms.py에서 아래의 폼 클래스를 추가

- 사용자 정보에 대한 폼과 프로필사진에 대한 폼을 각각 만들어 둔 뒤에 나중에 한번에 보여줄 예정

- views.py의 ProfileUodateView클래스의 get함수의 return값을 보면 이해됨.

from .models import Profile

# 프로필사진을 업데이트할 때 사용자의 정보도 같이 업데이트 할 수 있도록 사용자정보에 대한 폼, 프로필에 대한 폼 생성
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name','last_name']


class ProfileForm(forms.ModelForm):
profile_photo = forms.ImageField(required=False) # 선택적으로 입력할 수 있음.
class Meta:
model = Profile
fields = ['nickname','profile_photo']

2. kilogram/views.py에서 아래의 코드를 추가

- ProfileUpdateView의 get 함수는 프로필 편집하러 들어갔을 때 보여지는 정보를 표시해주는 기능을 함.

from django.views.generic.detail import DetailView
from django.views import View
from .forms import UserForm, ProfileForm
class ProfileUpdateView(View): # 간단한 View클래스를 상속 받았으므로 get함수와 post함수를 각각 만들어줘야한다.
# 프로필 편집에서 보여주기위한 get 메소드
def get(self, request):
user = get_object_or_404(User, pk=request.user.pk) # 로그인중인 사용자 객체를 얻어옴
user_form = UserForm(initial={
'first_name': user.first_name,
'last_name': user.last_name,
})

if hasattr(user, 'profile'): # user가 profile을 가지고 있으면 True, 없으면 False (회원가입을 한다고 profile을 가지고 있진 않으므로)
profile = user.profile
profile_form = ProfileForm(initial={
'nickname': profile.nickname,
'profile_photo': profile.profile_photo,
})
else:
profile_form = ProfileForm()

return render(request, 'kilogram/profile_update.html', {"user_form": user_form, "profile_form": profile_form})

3. 프로필편집 버튼을 누르며 편집 페이지로 넘어가도록 templates/kilogram/profile.html에서 링크 추가

<a href="{% url 'kilogram:profile_update' %}">

4. kilogram/urls.py에서 프로필 편집 url추가

url(r'^profile_update/$', login_required(views.ProfileUpdateView.as_view()), name='profile_update'),

5. templates/kilogram/의 위치에 profile_update.html 추가

{% extends 'account/base.html' %}
{% block content %}

<h1>{{user.username}} Profile Update</h1>

{% if error_msg %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<strong>Error</strong> {{error_msg}}
</div>
{% endif %}

<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" value="Update" />
</form>
</p>

{% endblock %}


6. views.py의 ProfileUpdateView클래스에 함수를 post함수를 추가해준다.

- Userform(request.POST) 여기까지만 하면 Userform에 해당하는 텍스트를 가져와서 객체를 생성하는 것인데

- Userform(request.POST, instance=u) 여기까지 해주면 u 객체의 내용을 request.POST로 받아온 텍스트로 교체한 그것으로 객체가 생성됨.

- 이 때 새로운 객체가 생성되는게 아님. 원래 객체의 내용이 수정되는 것이지.

- request.FILES는 이미지 업로드 할 때 사용함.

# 프로필 편집에서 실제 수정(저장) 버튼을 눌렀을 때 넘겨받은 데이터를 저장하는 post 메소드
def post(self, request):
u = User.objects.get(id=request.user.pk) # 로그인중인 사용자 객체를 얻어옴
user_form = UserForm(request.POST, instance=u) # 기존의 것의 업데이트하는 것 이므로 기존의 인스턴스를 넘겨줘야한다. 기존의 것을 가져와 수정하는 것

# User 폼
if user_form.is_valid():
user_form.save()

if hasattr(u, 'profile'):
profile = u.profile
profile_form = ProfileForm(request.POST, request.FILES, instance=profile) # 기존의 것 가져와 수정하는 것
else:
profile_form = ProfileForm(request.POST, request.FILES) # 새로 만드는 것

# Profile 폼
if profile_form.is_valid():
profile = profile_form.save(commit=False) # 기존의 것을 가져와 수정하는 경우가 아닌 새로 만든 경우 user를 지정해줘야 하므로
profile.user = u
profile.save()

return redirect('kilogram:profile', pk=request.user.pk) # 수정된 화면 보여주기
7. 사진 변경까지 정상적으로 됨.


반응형
Comments