기술블로그-Django편

📌 Django 템플릿에서 FBV / CBV 네임스페이스에 따라 분기 처리하는 방법

Chansman 2025. 5. 8. 18:26

📌 Django 템플릿에서 FBV / CBV 네임스페이스에 따라 분기 처리하는 방법

Django에서는 함수 기반 뷰(FBV)와 클래스 기반 뷰(CBV)를 혼용해 사용할 수 있습니다. 하지만 템플릿에서 URL 네임스페이스를 구분하지 않으면 원하지 않는 뷰가 호출되는 문제가 발생할 수 있습니다.


❗️ 문제 상황 요약

✅ 실수 포인트

  • 템플릿에서 {% url 'blog:update' blog.pk %} 형태로 URL을 하드코딩
  • FBV용 URLConf를 사용하는데, CBV용 템플릿을 그대로 사용
  • 결과적으로 FBV 뷰가 호출되지만 URL은 CBV 네임스페이스를 가리킴

🔍 이로 인해 reverse('blog:update')가 실행되며 의도한 URL과 다른 뷰로 이동하게 됨


✅ 해결 방법: 네임스페이스 분기 처리

✔️ 핵심 개념: request.resolver_match.namespace

  • 현재 요청된 URL의 네임스페이스(fb 또는 blog)를 확인 가능
  • 이를 기반으로 템플릿 내에서 URL 호출을 분기 처리할 수 있음

🧩 blog_detail.html 수정 예시

{% if request.resolver_match.namespace == 'fb' %}
  <a href="{% url 'fb:update' blog.pk %}">수정</a>
  <form action="{% url 'fb:delete' blog.pk %}" method="POST">
{% else %}
  <a href="{% url 'blog:update' blog.pk %}">수정</a>
  <form action="{% url 'blog:delete' blog.pk %}" method="POST">
{% endif %}
    {% csrf_token %}
    <button type="submit">삭제</button>
  </form>

{% if request.resolver_match.namespace == 'fb' %}
  <a href="{% url 'fb:list' %}">목록으로 돌아가기</a>
{% else %}
  <a href="{% url 'blog:list' %}">목록으로 돌아가기</a>
{% endif %}

📌 이처럼 템플릿 내에서 if 문을 활용해 네임스페이스에 따라 적절한 URL로 연결되도록 조정합니다.


🧩 base.html 수정 예시

<div>
  {% if request.resolver_match.namespace == 'fb' %}
    <a href="{% url 'fb:list' %}">홈</a>
  {% else %}
    <a href="{% url 'blog:list' %}">홈</a>
  {% endif %}
</div>

📌 공통 레이아웃에서도 동일하게 처리해야 헤더/네비게이션 영역에서 링크 오류가 발생하지 않습니다.


📊 정리 요약

항목 설명

네임스페이스 app_name = 'fb', app_name = 'blog' 로 URLConf에 정의된 구분자
문제 원인 템플릿은 하나인데 URL 네임스페이스가 달라 잘못된 뷰로 이동
해결 방법 request.resolver_match.namespace를 활용한 템플릿 내 분기 처리

💡 추천 전략 및 팁

전략 1: 템플릿 분리

  • blog/fbv_detail.html vs blog/cbv_detail.html 식으로 나누어 관리

전략 2: 네임스페이스 조건 분기

  • 하나의 템플릿을 공유하면서도 namespace를 기준으로 유연하게 처리 가능

🚫 흔한 실수: URL 하드코딩 후 복붙 사용 → 의도와 다른 네임스페이스로 이동

✔️ 예방 팁:

  • 항상 템플릿이 어떤 URLConf와 연결되는지 체크
  • 네임스페이스 기반 URL 사용 시 reverse() 오류 유의

앞으로 템플릿을 재사용할 땐, namespace 기반 URL 분기 처리를 습관화하세요.
의도하지 않은 뷰 호출 문제를 효과적으로 예방할 수 있습니다.