본문 바로가기
PROGRAMMING/Django

[Django] URL, namespace

by 안녕나는현서 2021. 9. 2.
728x90

Django URLs

  • Dispatcher(발송자, 운항 관리자)로서의 URL
  • 웹 애플리케이션은 URL을 통한 클라이언트의 요청에서부터 시작 됨

 

Variable Routing

  • URL 주소를 변수로 사용하는 것
  • URL의 일부를 변수로 지정하여 view 함수의 인자로 넘길 수 있음
  • 즉, 변수 값에 따라 하나의 path()에 여러 페이지를 연결 시킬 수 있음
  • [사용 예시]
    • path(‘/accounts/user/<int:user_pk>/’, …)
    • accounts/user/1 → (1번 user 관련 페이지)
    • accounts/user/2 → (2번 user 관련 페이지)

 

URL Path converters

  • str
    • / 를 제외하고 비어 있지 않은 모든 문자열과 매치
    • 작성하지 않을 경우 기본 값
  • int
    • 0 또는 양의 정수와 매치
  • slug
    • ASCII 문자 또는 숫자, 하이픈 및 밑줄 문자로 구성된 모든 슬러그 문자열과 매치
    • ex) ‘building-your-1st-django-site’

 

# articles > view.py > urlpatterns

path('greeting/<str:name>/', views.greeting)

 

App URL mapping

  • app의 view 함수가 많아지면서
    1. 사용하는 path() 또한 많아지고,
    2. app 또한 더 많이 작성되기 때문에
    3. 프로젝트의 urls.py에서 모두 관리하는 것은 프로젝트 유지보수에 좋지 않음
  • 이제는 각 app에 urls.py를 작성하게 됨
  • include()
    • 다른 URLconf(app1/urls.py)들을 참조할 수 있도록 도움
    • 함수 include()를 만나게 되면, URL의 그 시점까지 일치하는 부분을 잘라내고, 남은 문자열 부분을 후속 처리를 위해 include된 URLconf로 전달
  • django는 명시적 상대경로(from .module import ..)를 권장
# firstpjt > urls.py

from django.contrib import admin
from django.urls import path, include
from articles import views

urlpatterns = [
    path('admin/', admin.site.urls),

    # /articles/로 시작하는 모든 경로는 articles 앱의 urls.py로 전달
    path('articles/', include('articles.urls')),
    # /pages/로 시작하는 모든 경로는 pages 앱의 urls.py로 전달
    path('pages/', include('pages.urls')),
]
# articles > urls.py

from django.urls import path
# 현재 경로에 있는 views를 import
from . import views

urlpatterns = [
    path('index/', views.index),
    path('greeting/<str:name>/', views.greeting),
    path('dinner/', views.dinner),
    path('throw/', views.throw),
    path('catch/', views.catch),
]
# pages > urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('main/', views.index),
]

=> 각각의 앱 안에 urls.py를 생성하고 프로젝트 urls.py에서 각 앱의 urls.py 파일로 URL 매핑을 위탁

 

Naming URL patterns

  • 이제는 링크에 url을 직접 작성하는 것이 아니라 path() 함수의 name 인자를 정의해서 사용
  • Django는 URL에 이름을 지정하여 view 함수와 templates에서 특정 주소를 쉽게 참조할 수 있도록 도움
  • Django Template Tag 중 하나인 url 태그를 사용해서 path() 함수에 작성한 name을 사용할 수 있음
urlpatterns = [
    path('index/', views.index, name='index'),
    path('greeting/<str:name>/', views.greeting, name='greeting'),
    path('dinner/', views.dinner, name='dinner'),
    path('throw/', views.throw, name='throw'),
    path('catch/', views.catch, name='catch'),
]
  • url template tag
    • {% url '' %}
    • 주어진 URL 패턴 이름 및 선택적 매개변수와 일치하는 절대 경로 주소를 반환
    • 템플릿에 URL을 하드 코딩하지 않고도 DRY 원칙을 위반하지 않으면서 링크를 출력하는 방법
<a href="{% url 'index' %}">메인으로 가기</a>

 

Namespace (이름공간)

  • 객체를 구분할 수 있는 범위를 나타내는 말
  • 일반적으로 하나의 이름 공간에서는 하나의 이름이 단 하나의 객체만을 가리키게 된다.
  • 프로그래밍을 하다 보면 모든 변수명과 함수명 등 이들 모두를 겹치지 않게 정의 하는 것은 매우 어려운 일
  • 그래서 django에서는
    1. 서로 다른 app의 같은 이름을 가진 url name은 이름공간을 설정해서 구분
    2. templates, static 등 django는 정해진 경로 하나로 모아서 보기 때문에 중간에 폴더를 임의로 만들어 줌으로써 이름공간을 설정
      예) articles > templates > articles > index.html 구조

 

URL namespace

  • URL namespace를 사용하면 서로 다른 앱에서 동일한 URL 이름을 사용하는 경우에도 이름이 지정된 URL을 고유하게 사용 할 수 있음
  • urls.py에 “ app_name” attribute 값 작성
# articles > urls.py

from django.urls import path
from . import views

app_name = 'articles'

urlpatterns = [
    path('index/', views.index, name='index'),
    path('greeting/<str:name>/', views.greeting, name='greeting'),
    path('dinner/', views.dinner, name='dinner'),
    path('throw/', views.throw, name='throw'),
    path('catch/', views.catch, name='catch'),
]
  • : 연산자를 사용하여 지정
    • {% url ' app_name:name ' %} : app_name, name은 urls.py에 정의해놓은 이름으로!
<a href="{% url 'articles:index' %}">메인으로 가기</a>

 

Template namespace

  • Django는 기본적으로 app_name/templates/ 경로에 있는 templates 파일들만 찾을 수 있으며, INSTALLED_APPS에 작성한 app 순서로 tamplate을 검색 후 렌더링 함
  • 그래서 임의로 templates의 폴더 구조를 app_name/templates/app_name 형태로 변경해 임의로 이름 공간을 생성 후 변경된 추가 경로로 수정

def index(request):
    # return render(request, 'index.html')
    return render(request, 'articles/index.html')

  • 예를 들어, myapps와 tempapps 앱의 각각의 인덱스에 접근할 경우
    # myapps > views.py
    def index(request):
        return render(request, 'index.html')
       
    # tempapps > views.py
    def index(request):
        return render(request, 'index.html')
    각각의 index.html 파일은 각각 앱의 templates 폴더에 index.html로 정의되어 있다.
  • 하지만 url로 접근했을 때,
    myapps의 index

    tempapps의 index
    둘 다 myapps의 index.html이 보여지게 된다.
    → templates 폴더를 하나로 보기 때문에 url에 먼저 정의된 myapps만 보이게 된다!
  • 이를 해결하려면,
    파일구조를 myapps > templates > myapps > index.html 과 tempapps > templates > tempapps > index.html
    으로 변경시키면 된다.
728x90

댓글