Lina's Toolbox

Django의 URL namespace 본문

스파르타 내일 배움 캠프 AI 웹개발 과정/Django framework

Django의 URL namespace

Woolina 2024. 9. 2. 11:12

URL Namespace

우리의 프로젝트는 article과 user 두개의 앱을 가지고 있다.

우리는 url name을 참조하여 실제 url을 찾아가도록 하는데,

만약 두개의 앱에서 같은 name을 쓴다면 어떻게 될까?

(articles/urls.py에도 hello/ url이 있고, users/urls.py에도 hello/가 있다면?)

 

articles/urls.py

from django.urls import path
from . import views

urlpatterns = [
    ...
    path("hello/", views.hello, name="hello"),
    ...
]

 

 

users/urls.py

from django.urls import path
from . import views

urlpatterns = [
    ...
    path("hello/", views.hello, name="hello"),
    ...
]

 둘다 hello라는 url name을가지고, 인덱스에서 해봤더니 항상 articles의 앱으로 간다.

왜?

setting.pyinstalled_apps의 순서에 비밀이 있다.

장고는 여기 적혀있는 순서대로 모든 것을 찾는다.(url, templates .... 모두)

두개 순서를 바꾼다음에 해보면 users/hello로 간다.

 

😗 hello/는 동일하지만 하나는 articles/hello/, 다른 하나는 users/hello/라서 다른데 이 정도는 구분하지 않을까요?

그런데 만약 
{% url 'hello' %} # 어디로 가죠?

redirect('hello') # 어디로 가야할까요?​
⇒ 그러니까 url namespce를 적용해봅시다!

index, create 같은 것들은 겹칠 가능성이 많겠죠?

항상 article_create, user_create처럼 해줘도되겠지만 귀찮죠?

→ 네임스페이스 만든다.

그안에서 url관리하도록 한다.

(먼저 네임스페이스를 보고, 그다음에 url 보도록  url이 같아도 네임스페이스가 다르니 괜찮아진다.)

 

 

URL Namespace

  • Django는 서로 다른 앱에서 동일한 URL Name을 사용하는 경우, 고유하게 구분할 수 있도록 namespace를 지원합니다.
from django.urls import path
from . import views

app_name = "articles"

urlpatterns = [
		...
    path("hello/", views.hello, name="hello"),
    ...
]

 

url에 이름공간을 만들어주고 나면, namespace:url_name형태로 사용합니다.

{% url 'articles:hello' %}

redirect('articles:hello')

 app_name = "articles" 해주면 이 문장 써주는 순간 네임스페이스 적용 

→ 이제 url pattern에서 사용하는 이름들은

templates에서 이제는 {% url 'hello' %} 가 아닌 {% url 'articles:hello' %} 이런식으로 참조해줘야한다.

프로젝트 처음에 만들 때부터 이렇게 해주자.

 

 

에러 발생

  • 이전의 형태로 사용하면 에러가 발생합니다.

  • 수정하기
    articles

 

 

users

{% url 'profile' %}  -> {% url 'users:profile' %}

redirect('profile') -> redirect('users:profile')

 

views의 redirect도 articles 말고 articles:articles로 해주자

 

 

namespace를 준 순간,

그냥 create적으면 안되고 appname:create해줘야한다.

안그러면 에러남.

 

 

만약 articleshello.html 파일을 지워버린다면?

usershello.html로 간다.

→ installed_apps 순서대로 다 뒤져보고 "articles",도 없으니 "users",로 간 것!


Templates 구조

만약, 내가 똑같은 이름의 템플릿을쓰고싶다면?

템플릿도 url처럼 namespace같은 형식을 만들수는 없을까?

 

현재 우리는

"index.html"만 적어주면 django가 알아서 찾아옵니다.

 

만약, users앱에도 index.html이 있고 articles앱에도 index.html 이 있다면 어떻게 될까요?

{% extends "base.html" %}


{% block content %}
    <h1>여기는 Users App의 INDEX</h1>
{% endblock %}

users/templates/index.html

 

/index/로 들어가보면,

⇒ 오, django가 똑똑하게 잘 가져오고 있는데요?!

 

그런데 이렇게 바꾸면 어떻게 될까요?

 

다시 /index/로 들어가보면,

 

⇒ 즉, Django는 Apps를 하나씩 돌면서 App 안에 templates가 있으면 들어가서 이름과 일치하는 템플릿을 꺼내오는 로직을 반복하는 것입니다!

→ 그럼 매번 우리가 App 순서를 신경쓰면서 작업해야 할까요? 😭

 

 

장고에서 권장하는 구조는

app이름의 디렉토리 안쪽에 / 템플릿/ 앱네임 / html파일들

→ 햄버거같은 구조!

 

Templates Namespace 만들어주기

  • <app_name>/templates/<app_name>으로 구조 만들기

 

→ 그리고 이제부터 view에서 템플릿을 사용할 때는 <app_name>/template.html 으로 사용하면 됩니다!

(articles/index.html 이런식)

 

users앱도 같은 방법으로 해주자

 

프로젝트 처음부터 이런 식으로 작성해 주자.