본문 바로가기

Backend/Django

2022-02-25::Django 29-35

29. Dynamic URL Routing

path('prudcts/<int:my_id>', dynamic_lookup_view, name="product"),

요청 url 다음에 오는 값을 동적으로 받아서 처리할 수있다. 이 경우에는 int형의 데이터 my_id로 값을 받았다.

해당 값은 비즈니스 로직 dynamic_lookup_view로 전달된다.

def dynamic_lookup_view(req, my_id):
    obj = Product.objects.get(id=my_id)
    context = {
        "object": obj
    }
    return render(req, "products/product_detail.html", context)

dynamic_lookup_view의 인자를 보면 다른 함수와 다르게 my_id가 있다. 이는 url로부터 동적으로 받은 int형 변수이다.

이를 통해 동적으로 URL 요청을 처리할 수 있다.

30. Handle DoesNotExist(404)

def dynamic_lookup_view(req, my_id):
    obj = get_object_or_404(Product, id=my_id)
    # try:
    #     obj = Product.objects.get(id=my_id)
    # except Product.DoesnotExist:
    #     raise Http404
    context = {
        "object": obj
    }
    return render(req, "products/product_detail.html", context)

31. Delete and Confirm

DB에서 데이터를 삭제하는 것은 쉽다. 하지만 GET 이 아닌 POST method에서만 동작하도록 최소한의 검증을 해야한다.

def dynamic_delete_view(req, my_id):
    obj = get_object_or_404(Product, id=my_id)
    # only on POST req
    if req.method == "POST":
        obj.delete()
        return redirect('../../')
    context = {
        "object": obj
    }
    return render(req, "products/product_delete.html", context)

32. View of a List of DB objecst

queryset = Product.objects().all()

33. Dynamic Linking of URLs

같은 url이 template등에서 반복되어 사용된다. 이런 경우 전체적인 변경이 어렵다. 따라서 모델 클래스에 다음과 같은 매서드를 추가해 문제를 막을 수 있다.

def get_absolute_url(self):
	return f"/products/{self.id}/"

34. Django URLs Reverse

이전까지는 역시 urls.py로 관리되는 경로를 그대로 문자열로 가져와서 접근했다. 이제는 반대로 urls.py에 지정된 이름을 가져와 동적으로 경로를 설정해줄 수 있다. url을 통해 전달하는 인자들을 kwarg으로 전달된다.

import django.urls import reverse

def get_absolute_url(self):
	return reverse("product-detail", kwargs={"id": self.id})

35. In App URLs and Namespacing

현재 urls.py에서 관리되는 경로들은 모두 절대경로이다. 또한 같은 keyword를 사용하는 경우 충돌이 발생할 수 있다. 때문에 앱 디렉터리 안에 urls.py를 따로 생성해서 해당 경로를 관리한다.

from django.urls import path
from .views import (
    product_create_view,
    product_detail_view,
    product_list_view
)

app_name = 'products'
urlPatterns = [
    path('', product_list_view, name='product-list'),
    path('create/', product_create_view, name='product-list'),
    path('<int:id>/', product_detail_view, name='product-detail'),
    # path('<int:id>/update/', product_update_view, name='product-update'),
    # path('<int:id>/delete/', product_delete_view, name='product-delete')
]

인앱의 경로에는 base_url (이 경우에는 'products/')를 제외한 경로를 지정해 준다.

또한 인앱 경로의 name이 유일성을 보장해주지 않으니 app_name이라는 nameSpace를 반드시 지정하여 사용해야 한다.

모델에서 경로를 사용할 때 다음과 같이 namespace를 포함한 형태로 수정해 주자.

return reverse("products:product-detail", kwargs={"id": self.id})

 

그리고 메인 urls.py파일에 인앱 url 경로를 다음과 같이 추가해 준다.

from django.urls import include, path

urlPatterns = [
	path('products/', include('products.urls')),
    ...
]

 

 

'Backend > Django' 카테고리의 다른 글

2022-03-02::DRF Requests and Responses  (0) 2022.03.02
2022-03-01::DRF Serialization  (0) 2022.03.02
2022-02-24::Django Forms  (0) 2022.02.24
2022-02-24::Django Read, Create with sqlite3  (0) 2022.02.24
2022-02-20::Django models  (0) 2022.02.21