문제 현상
- 이메일에 잘못된 형식이 들어가도 에러메시지가 뜨지 않음
- 그냥 DB에 저장도 되지 않고 다음 페이지로 리다이렉트 됨
원인
def post(self, request):
current_user = User.objects.get(pk=request.user.pk)
user_form = UserForm(request.POST, instance=current_user)
if user_form.is_valid():
user_form.save()
# PROFILE UPDATE
if hasattr(current_user, "profile"):
profile = current_user.profile
profile_form = ProfileForm(
request.POST, request.FILES, instance=profile)
# PROFILE CREATE
else:
profile_form = ProfileForm(request.POST, request.FILES)
if profile_form.is_valid():
# PROFILE CREATE의 경우 USER와 연결이 필요함
profile = profile_form.save(commit=False)
profile.user = current_user # Profile 모델의 user에 current_user 지정
profile.save()
return redirect("accounts:profile", slug=request.user.profile.slug)
- 하나의 액션에 폼을 2개 사용하고 있는 상황
- 자세히 보면 user_form이 유효하지 않을 때 처리해주는 구문이 없음
def post(self, request):
current_user = User.objects.get(pk=request.user.pk)
user_form = UserForm(request.POST, instance=current_user)
if user_form.is_valid():
user_form.save()
- 이 부분에서 user_form의 이메일 input이 유효하지 않기 떄문에 그냥 통과
- 그 후 마지막 줄 return redirect로 프로필 페이지로 이동
- 결과적으로 user_form이 DB에 저장되지 않고 리다이렉트 됨
시도
- 일단 유저폼과 프로필폼 유효성 검사문을 하나로 묶었음
- 그리고 폼 2개가 모두 유효할 때만 DB에 저장하고 프로필 페이지로 리다이렉트
- 유효하지 않다면 input next에 담긴 이전 페이지로 리다이렉트
if profile_form.is_valid() and user_form.is_valid():
# PROFILE CREATE의 경우 USER와 연결이 필요함
profile = profile_form.save(commit=False)
profile.user = current_user # Profile 모델의 user에 current_user 지정
profile.slug = request.POST.get('nickname')
profile.save()
user_form.save()
return redirect("accounts:profile", slug=request.user.profile.slug)
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% render_field profile_form.profile_photo class="profile_photo" %}
<ul>
<li class="input-data"><label for="name">성</label>{% render_field user_form.first_name class="name" %}</li>
<li class="input-data"><label for="name">이름</label>{% render_field user_form.last_name class="name" %}</li>
<p>사람들이 이름, 별명 또는 비즈니스 이름 등 회원님의 알려진 이름을 사용하여 회원님의 계정을 찾을 수 있도록 도와주세요</p>
<li class="input-data"><label for="name">사용자 이름</label>{% render_field profile_form.nickname class="nickname" %}</li>
<li class="input-data"><label for="email"">이메일</label>{% render_field user_form.email class="email" %}</li>
<li class="input-data"><label for="submit"></label><input type="submit" value="제출" /></li>
</ul>
<input type="hidden" name="next" value="{{ request.path }}">
</form>
- 그리고 redirect로 에러메시지를 정달해줘야해서 구글링을 해봤지만 실패...
- redirect로는 값을 전달 못한다고 함
- render로 해도 되지만 다시 get 메소드처럼 코드를 만들고 싶지 않았음
- next로 이전페이지로 리다이렉트되는걸 유지하면서 메시지를 표시하고 싶었음
- 좀 더 찾아보니 장고에는 messages라는 프레임워크가 있음
- 프론트페이지에서 전역적으로 사용할 수 있는 듯함
- 자세한 내용은 여기
- 중요도별로 메시지 등급을 나눌 수 있고 try except 문으로 감싸서 에러가 나면 사용할 수 있는듯함
해결
def post(self, request):
try:
current_user = User.objects.get(pk=request.user.pk)
user_form = UserForm(request.POST, instance=current_user)
# PROFILE UPDATE
if hasattr(current_user, "profile"):
profile = current_user.profile
profile_form = ProfileForm(
request.POST, request.FILES, instance=profile)
# PROFILE CREATE
else:
profile_form = ProfileForm(request.POST, request.FILES)
# PROFILE CREATE의 경우 USER와 연결이 필요함
profile = profile_form.save(commit=False)
profile.user = current_user # Profile 모델의 user에 current_user 지정
profile.slug = request.POST.get('nickname')
profile.save()
user_form.save()
return redirect("accounts:profile", slug=request.user.profile.slug)
except Exception:
messages.add_message(request, messages.ERROR, "형식이 올바르지 않습니다.")
next = request.POST.get('next', '/')
return HttpResponseRedirect(next)
- try문으로 묶어서 폼이 유효하지 않으면 오류가 나도록 if valid 부분을 없앰
<input type="hidden" name="next" value="{{ request.path }}">
{% if messages %}
{% for message in messages %}
<p{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{message}}</p>
{% endfor %}
{% endif %}
</form>
- messgae가 하나라도 for문 돌려야 된다고 함
- 이유는 그렇지 않으면 이전 message가 깨끗하게 정리되지 않는다고 함
배운점
- 리다이렉트로는 추가적인 정보를 전달하지 못함
- 장고에 내장된 messages 프레임워크을 잘 활용하자
'Backend > Python' 카테고리의 다른 글
[인스타그램 클론] 단일 페이지에 모델 폼 추가하기 (0) | 2020.06.17 |
---|---|
[인스타그램 클론] Vanilla JS - AJAX (0) | 2020.06.08 |
중복값 갯수(collections.Counter) (0) | 2020.05.02 |
[인스타그램 클론] 프로필 페이지 (0) | 2020.04.28 |
form 이미지 업로드 (0) | 2020.04.22 |