django에서 url패턴을 정의하기 위해서 path와 re_path를 사용한다.
path
path는 Django2.0에 도입된 함수로, 보다 간결하고 직관적인 방식으로 URl 패턴을 정의할 수 있게 해 준다. 정규식 표현을 사용하지 않고도 url 패턴을 쉽게 작성할 수 있다.
path는 경로 변수의 타입을 명시할 수 있는 기능을 제공하는데, 기본적으로 지원하는 타입은 str, int, slug, uuid, path 등이 있다.
re_path
re_path는 Djang2.0 이전에 사용되던 url 함수의 대체품으로, 여전히 정규 표현식을 사용하여 url 패턴을 정의할 수 있도록 한다. 보다 복잡한 URL 패턴이 필요한 경우 re_path를 사용할 수 있습니다.
path & re_path 사용
일반적으로 간단한 URL 패턴을 정의할 때는 path를 사용하는 것이 더 좋다. 최신에 업데이트된 만큼 가독성이 높고, 유지보수가 쉬우며 대부분의 URL패턴을 충분히 처리할 수 있다. 그러나 정규식 표현이 필요한 복잡한 패턴의 경우는 re_path를 사용하는 것이 좋다.
정규식 패턴을 엄격하게 지정할 경우 불필요한 view 호출을 줄일 수있다.
- 모든 미들웨어가 호출되고 View가 호출되고 데이터베이스까지 조회하고 나서야 404 오류 응답 >> 서버 리소스 낭비
- View 인자를 그대로 Raw SQL 쿼리 작성에 사용될 때 예상치 못한 쿼리로 SQL Injection 공격에 노출될 수도 있습니다.
- 아래의 경우 숫자 패턴이 아닌 경우에는 매칭되지 않고 다음 패턴을 검사합니다.
- 숫자 패턴인 경우에만 cover_png 뷰를 호출합니다.
from django.urls import re_path, path
path(route="<int:pk>/")
re_path(route=r"^(?P<pk>\d+)/$")
path(route="<uuid:uuid>/")
re_path(route=r"^(?P<uuid>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/$")
path(route="<slug:slug>/")
re_path(route=r"^(?P<slug>[-a-zA-Z0-9_]+)/$")
path(route="<path:path>/")
re_path(route=r"^(?P<path>.+)/$")
path(route="<str:username>/")
re_path(route=r"^(?P<username>[^/]+)/$")
CustomConverter
Django의 url 패턴 매칭 시스템은 강력하고 유연하게 처리할 수 있지만, 기본으로 지원하는 타입으로만 부족할 경우가 있는데, 이럴 때 Custom Converter를 이용하여 특정 패턴에 맞춰서 처리할 수 있도록 할 수 있다.
custom converter 클래스 정의
만약 regex = r"\d {4}/\d {1,2}/\d {1,2}"로 할 경우 2223/12/32/ 와 같은 요청도 매칭되어 관련 View가 호출되고 데이터베이스를 조회하지만, 관련 데이터가 없습니다.
아래처럼 정규식을 조금 더 엄격하게 함으로써 불필요한 요청을 사전에 걸러낼 수 있다.
regex = r"20\d {2}/([1-9]|0 [1-9]|1 [0-2]){1,2}/([1-9]|0 [1-9]|[12][0-9]|3 [01]){1,2}"
- year: 2000 ~ 2099
- month: 1, 2, 3, 4, 5, 6, 7, 8, 9, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12
- day : 1, 2, 3,.. 9, 01, 02, 03,.. 09, 10, 11, 12,.. 30, 31
from datetime import date
from django.urls import register_converter
class DateConverter:
regex = r"20\d{2}/([1-9]|0[1-9]|1[0-2]){1,2}/([1-9]|0[1-9]|[12][0-9]|3[01]){1,2}"
# 뷰 함수에 넘기기 전에 date 객체로 변환
# - ex) "2023/12/25" -> date(2023, 12, 25)
def to_python(self, value: str) -> date:
year, month, day = map(int, value.split("/"))
return date(year, month, day)
def to_url(self, value: date) -> str:
return f"{value.year}/{value.month:02d}/{value.day:02d}"
# DateConverter를 등록합니다.
register_converter(DateConverter, "date")
URL 등록
from django.urls import path, re_path
from . import converters # noqa : 임포트되어야만 커스텀 컨버터가 등록됩니다.
from . import views
urlpatterns = [
path(route="archives/<date:release_date>/", view=views.index),
]
'BackEnd > Django, DRF' 카테고리의 다른 글
[Django] Django에서 Slug란? (0) | 2024.06.17 |
---|---|
[Django] django-debug-toolbar (0) | 2024.06.11 |
[Django] 동적 이미지 생성, CSV & 엑셀 응답을 처리하는 View 만들기 (0) | 2024.06.10 |
[Django] timezone 모듈과 datetime 모듈의 차이 & 사용법 (1) | 2024.06.04 |
[DRF] Django로 일간 및 주간 조회수 구현하기: 코드 예제 (0) | 2024.06.04 |