Old Branch

Django - tweetme 소셜서비스 구현해보기 (11) - Dynamic URL Routing

woolbro 2019. 10. 28. 01:29
반응형

이번 포스팅은 Django의 url과 관련한 포스팅입니다.

 

Dynamic URL Routing에 대해 포스팅 하도록 하겠습니다. 간단한 예제와 프로그래밍으로 설정 해 보도록 하겠습니다.

 

Django 1.10 버전으로 진행하기 때문에 현재 Django2.2 버전과 차이가 좀 있습니다. 

 

tweetme application이 모두 작성 된 후에 Django 2.2 버전으로 업그레이드 해 보도록 하겠습니다.

 

본 포스팅의 소스는 Github에 업로드 되어 있습니다.

 


1. Dynamic URL

이전에 작성했었던 url 중, detail_view에서는 tweet번호를 1로 설정 했을 경우에 접근이 가능했습니다.

 

 

캡쳐화면을 보면 입력한 url 은 /tweet/2 로, 우리가 url매핑을 해주지 않았습니다.

즉, 뒤의 1을 유동적으로 바뀌어 질 수 있도록 설정하면, tweet/1 외에도 접근을 할 수 있습니다.

 

우선, url을 아래와 같이 수정 해 주도록 하겠습니다.

tweet앱의 urls.py을 수정 해 주도록 하겠습니다.

from django.conf.urls import url,include
from django.conf import settings
from .views import tweet_detail_view, tweet_list_view, TweetListView, TweetDetailView

urlpatterns = [
    url(r'^$', TweetListView.as_view(), name='list'),
    url(r'^(?P<pk>\d+)/$', TweetDetailView.as_view(), name='detail')
]

정규표현식에 맞게 위와같이 작성 했습니다.

 

<pk>라고 작성했는데, 저기에 들어갈 것이 바로 argument라고 합니다. 장고에서는 kwargs로 볼 수 있습니다.

 

tweet앱의 views.py의 TweetDetailView에 print문을 아래와 같이 추가 해 줍니다.

class TweetDetailView(DetailView):
    #template_name = "tweets/detail_view.html"
    queryset = Tweet.objects.all()

    def get_object(self):
        print(self.kwargs)
        return Tweet.objects.get(id=1)

 

위와같이 작성이 완료 되었다면 서버를 실행시켜, url에 접근 해 보도록 하겠습니다.

 

localhost:8000/tweet/13 으로 접근 했을 경우 아래와 같이 나옵니다.

 

 

여기서 중요 한 것은 오른쪽 Terminal의 {'pk':'13}으로 출력 된 모습입니다.

 

TweetDetailView의 get_object()에서, Tweet.objects.get(id=1) 때문에 어떤 url 을 입력해도 첫번째 트윗만 나올 것입니다.

 

하지만 입력한 url의 마지막 숫자를 pk로 받아올 수 있게 작성을 해 주었기 때문에 이를 이용해서 다른 트윗도 출력을 해 주도록 하겠습니다.

 

 

tweet앱의 views.py의 TweetDetailView에 pk를 가져와서 쿼리에 적용 시켜보겠습니다.

class TweetDetailView(DetailView):
    #template_name = "tweets/detail_view.html"
    queryset = Tweet.objects.all()

    def get_object(self):
        print(self.kwargs)
        pk = self.kwargs.get("pk")
        return Tweet.objects.get(id=pk)

pk를 kwargs에서 가져와 tweet id에 대응시켜주고 있습니다. 

 

작성이 완료되면 아래와 같이 다른 트윗들을 연결 할 수 있습니다.

 

tweet이 존재 하지 않을 경우 page not found 처리를 해 주기 위해서 "get_obejct_or_404" 모듈을 추가 해 주도록 하겠습니다.

 

TweetDetailView에 아래와 같이 get_obejct_or_404 모듈을 추가 해 주고, get_object 함수까지 수정 해 주세요.

from django.shortcuts import render,get_object_or_404
from django.views.generic import DetailView, ListView

from .models import Tweet
# Create your views here.


class TweetDetailView(DetailView):
    #template_name = "tweets/detail_view.html"
    queryset = Tweet.objects.all()

    def get_object(self):
        print(self.kwargs)
        pk = self.kwargs.get("pk")
        obj = get_object_or_404(Tweet,pk=pk)
        return Tweet.objects.get(id=pk)

 

작성에 성공하면 페이지를 찾을 수 없을 때 아래와 같이 출력합니다.