python

Django | URLConf 에서 lambda의 활용

씨치 2022. 12. 7. 00:04

- 문제상황
Django 실습을 하면서 URLConf를 설정해 주다가 만약 사용자가 localhost:8000/ 으로 접속한다고 가정했을 때 localhost:8000/hotdeal/ 로 redirect를 해주려면 어떻게 코드를 작성할 지 고민

 

 

localhost:8000/ 을 치고 엔터를 눌렀을 때 localhost:8000/hotdeal/로 redirect 하려면?


- 해결방안

프로젝트 관리 폴더에 views.py, urlpatterns에 함수 및 path 추가

# project_name/urls.py
from django.urls import path, include
from .views import redirect_func

urlpatterns = [
    path('hotdeal/', include('hotdeal.urls')),
    path('', redirect_func),
]
# project_name/views.py
from django.shortcuts import redirect

def redirect_func(request):
	return redirect('hotdeal/')

이런식으로 작성하면 해결되는 문제이긴 한데, project 관리 폴더의 views.py는 데이터를 처리하지도 않는데 굳이 만들어주어야 하나 싶은 생각이 들었다.


- 좀 더 나은 해결방안?

 

views.py를 만들지 않고 path() 안에는 파라미터로 home url과 함수의 주소만 들어가기 때문에 path 뒤에는 람다 함수를 이용해서 쓸 수 있지 않을까 하는 아이디어가 떠올랐다.

 

위의 코드를 개선한 코드는 다음과 같다.

# project_name/urls.py
from django.urls import path, include
from django.shortcuts import redirect


urlpatterns = [
    path('hotdeal/', include('hotdeal.urls')),
    path('', lambda x: redirect('hotdeal/')),
]

이렇게 작성한다면, 굳이 views.py 파일을 만들지 않아도 redirect가 가능하다.

대신 urls.py에는 redirect를 import 시켜야 한다는 것을 잊지 말자!

 

위의 코드에서 lambda x: redirect('hotdeal/') 로 적어주었는데, lambda에서 x를 꼭 적어주어야 하는 이유는 views.py에서 함수를 선언할 때 request를 파라미터로 받아주기 때문이다. return 값에서 필요한 것은 아니지만, request는 들어가기 때문에 lambda: redirect('hotdeal/') 로 적게 된다면 오류가 발생하게 된다. (input 파라미터가 없음)

 

 

그러면, 데이터를 처리해주는 view도 람다로 처리할 수는 없을까?

 

좋은 방법은 당연히 아니겠지만, 람다함수를 연습할 겸 코드를 바꿔보자면,

# hotdeal/urls.py
from django.contrib import admin
from django.urls import path
from .views import index

app_name = 'hotdeal'
urlpatterns = [
    path('', index)
]
# hotdeal/views.py
from django.shortcuts import render
from .models import Deal

# Create your views here.
def index(request):
    data = Deal.objects.all().order_by('-createdAt') # select * from deal order by createdAt desc;
    return render(request, 'hotdeal/index.html', {"data": data})

위의 gif에서 나오는 것처럼, deal table에서 쿼리해서 가져와 index.html을 render해 리턴해주는 index 함수가 views.py에 정의되어 있다. 이걸 람다 함수로 바꾸면 어떤 식으로 작성할 수 있을지 테스트해 봤다.

 

# hotdeal/urls.py
from django.contrib import admin
from django.urls import path
from .models import Deal
from django.shortcuts import render

app_name = 'hotdeal'
urlpatterns = [
    path('', lambda request: render(request, 'hotdeal/index.html', {'data': Deal.objects.all().order_by('-createdAt')} ))
]

작동은 잘 하는 걸 확인할 수 있다.

하지만 URL Conf 파일에 Deal model을 import 해주어야 하고, django.shortcuts의 render 함수도 import 해주어야 하기 때문에 쓸데없는 import가 많아지는 문제가 있다. ( 당연히 이렇게는 안쓸듯 )

어디까지나 연습이기 때문에 위의 코드는 재미로만 봐주길 바라고, 이런 식으로도 작성할 수 있겠구나! 하고 넘어가면 될 듯 하다.