작정하고 Django 33강 - get_success_url 함수 그리고 리팩토링

_·2023년 12월 28일

작정하고 Django 강의

목록 보기
32/44

코드 수정

success_url

프로필은 수정하고 나서 그 계정의 페이지로 가는것이 좋기 때문에 profileapp의 views.py에서 success_url = reverse_lazy('accountapp:detail') 로 수정

detail 페이지는 accountapp/urls.py에서 pk라는 추가적인 데이터가 가야함

하지만 위 코드의 경우 ProfileCreateView라는 클래스의 직접적인 파마리터 CreateView를 넘겨주기 때문에 위처럼 success_url을 설정해주는 것은 추가적인 데이터를 동적으로 보내줄 수 없다.

따라서 내부 메소드를 정의해야 한다.

success_url = reverse_lazy('accountapp:detail')

위처럼 넘겨주는 pk 를 다음의 내부 메소드에서 kwargs = {'pk':self.object.user.pk} 와 같이 넘겨준다.
self.object가 가리키는 것은 model = Profile이다.

즉, 연결되어있는 Profile의 user의 pk를 찾아서 kwargs={'pk':self.object.user.pk}로 넘겨주는 것.
그 다음에는 reverse에 의해서 user 본인의 detail페이지로 redirect 된다.
이것을 ProfileUpdateView에도 적용시켜준다.

# profileapp/views.py
class ProfileCreateView(CreateView):
    model = Profile
    context_object_name = 'target_profile'
    form_class = ProfileCreationForm
    template_name = 'profileapp/create.html'
    
    def form_valid(self, form):
        temp_profile = form.save(commit=False)
        temp_profile.user = self.request.user
        temp_profile.save()
        return super().form_valid(form)
        
    # 추가    
    def get_success_url(self):
        return reverse('accountapp:detail', kwargs={'pk': self.object.user.pk})

@method_decorator(profile_ownership_required, 'get')
@method_decorator(profile_ownership_required, 'post')
class ProfileUpdateView(UpdateView):
    model = Profile
    context_object_name = 'target_profile'
    form_class = ProfileCreationForm
    success_url = reverse_lazy('accountapp:hello_world')
    template_name = 'profileapp/update.html'

	# 추가
    def get_success_url(self):
        return reverse('accountapp:detail', kwargs={'pk': self.object.user.pk})

테스트

123 을 빼고 수정버튼을 눌렀을 때 자신의 detail 페이지로 오는 것을 확인

edit 링크 수정

로그아웃을 해도 edit 링크가 보이는 문제점이 발생
accountapp/templates/accountapp/detail.html → 수정 필요

원래 코드의 문제점

프로필이 있으면 nickname을 보여주는 동시에 추가적인 인증 과정 없이 이 edit로 향하고, 프로필이 없으면 마찬가지로 인증 없이 Create Profile을 보여줘 프로필 수정 페이지를 향하는 링크를 보여주는 문제

해결

우선 이미지와 대화명도 "profile 이 있을 때" 보여주도록 if문 내부로 이동
다음과 같이 target_user == user면 정상적으로 각각 editCreate Profile링크가 보여지도록 수정

테스트

이 프로필의 주인이 아니라면 edit 즉 수정페이지가 보이지 않음.
프로필이 제대로 설정되어있지 않은 계정의 경우, 닉네임 미설정 문자열 출력

전체 코드

{% extends 'base.html'%}

{% block content %}

  <div>
    <div style="text-align: center; max-width: 500px; margin: 4rem auto;">
      <p>
        {{ target_user.date_joined }}
      </p>
      {% if target_user.profile %} <!--(1) profile 있고 -->
      <!--프로필 이미지를 보여주기-->
      <img src="{{ target_user.profile.image.url }}" alt=""
           style="height: 12rem; width: 12rem; border-radius: 20rem; margin-bottom: 2rem;">
      <h2 style="font-family: 'NanumSquareB'">
        <!--nickname 보여주기-->
        {{ target_user.profile.nickname }}
          <!-- 추가된 부분 -->
          {% if target_user == user %} <!--(1-1) target_user == user 라면-->
          <!--프로필 수정 페이지로 이동할 수 있도록-->
          <a href="{% url 'profileapp:update' pk=target_user.profile.pk %}">
            edit
          </a>
          {% endif %}
          <!--------------->
      </h2>
      <!--대화명을 보여주기-->
      <h5 style="margin-bottom: 3rem;">
        {{ target_user.profile.message }}
      </h5>

      {% else %} <!--(2) profile 이 없는데-->
        <!-- 추가된 부분 -->
        {% if target_user == user %} <!-- (2-1) target_user == user 이라면-->
        <!--프로필 생성 페이지로 이동할 수 있도록-->
        <a href="{% url 'profileapp:create' %}">   
          <h2 style="font-family: 'NanumSquareB'">
            Create Profile 
          </h2>
        </a>
        <!-- (2-2) 단순히 프로필만 없다면-->
        {% else %}
        <h2>
          닉네임 미설정 <!--다음 출력-->
        </h2>
        {% endif %}
        <!--------------->

      {% endif %}

      {% if target_user == user %}
      <a href="{% url 'accountapp:update' pk=user.pk%}">
        <p>
          Change Info
        </p>
      </a>
      <a href="{% url 'accountapp:delete' pk=user.pk%}">
        <p>
          Quit
        </p>
      </a>
      {% endif %}
    </div>
  </div>

{% endblock %}

commit

0개의 댓글