관리 메뉴

Storage Gonie

33. (app2) generic view를 적용한 Class-based views 방식의 URL 라우팅 본문

웹개발/Django 웹서비스 개발(인프런)

33. (app2) generic view를 적용한 Class-based views 방식의 URL 라우팅

Storage Gonie 2019. 2. 19. 22:10
반응형
"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""

# URL을 라우팅 하는 방법 3가지

1) Function views

- url 규칙, views.함수명, name

- HTTP메소드인 POST, GET 과 같은 함수들을 if POST, else GET 이런 방식으로 처리해야함

- 간단한 것을 구현할 때 좋다.

url(r'^$', views.home, name='home')

2) Class-based views

- url 규칙, 클래스명.as_view(), name

- HTTP메소드인 POST, GET 과 같은 함수들을 클래스의 한 메소드랑 연결시켜줄 수 있다.

- 상속, 객체지향의 장점을 적용해서 가독성, 재사용성을 높일 수 있고, 좀 더 복잡한 것을 구현할 수 있게 해준다.

url(r'^$', Home.as_view(), name='home')

3) Including another URLconf

- url 규칙, include(urls파일의 경로)

url(r'^blog/', include('blog.urls'))


# generic view(Class-based generic view)

- 일반적인 웹페이지에서 많이 사용하는 기능을 장고에서 제공해주는 것.

- 코드를 단순화 해주고, 빠른 개발을 가능하게 함.

<index.html>

- '오브젝트들의 리스트'를 가져와서 각각의 오브젝트에 대한 간단한 내용을 표시해 줌.

- 이런것들을 간단히 처리할 수 있게 장고에서는 generic.ListView를 제공해준다.

<detail.html과 results.html>

- 보여주는 모양은 다르지만 '한 객체를 가지고 그것의 세부 정보'를 보여줌.

- 이런것을 간단히 처리할 수 있게 장고에서는 generic.DetailView를 제공해준다.


1. polls.urls.py에서 function views 방식으로 구현된 라우팅을 Class-based views 방식으로 교체한다.

- generic.ListView를 상속받은 클래스 IndexView에서는 클래스 내부의 메소드에서 지정한 객체를 직접 꺼내오므로 파라미터를 받지 않는다.

- generic.DetailView를 상속받은 클래스 DetailView와 ResultsView를 사용할 때는 url에서 매개변수를 'pk' 이름으로 넘겨줘야한다.

app_name = 'polls'

urlpatterns = [
url(r'^$', views.index, name = 'index'),
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name = "detail"),
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name = "results"),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name = "vote"),
]
app_name = 'polls'

urlpatterns = [
#리스트뷰는 똑같은 것만 보여주는 페이지 이기 때문에 파라미터를 받지 않는다.
url(r'^$', views.IndexView.as_view(), name = 'index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name = "detail"),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name = "results"),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name = "vote"),
]


2. views.py에 generic을 import하고 generic을 상속받은 IndexView, DetailView, ResultsView 클래스를 생성한다.

from django.views import generic

IndexView 클래스는 객체들의 리스트를 템플릿으로 넘겨주므로 generic.ListView를 상속받아 만들어진다.

'''
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5] # order_by('속성명') : 오름차순, ('-속성명') : 내림차순
context = {'latest_question_list' : latest_question_list}
return render(request, 'polls/index.html', context)
'''

class IndexView(generic.ListView): # 객체를 리스트 형태로 전달하기 때문에 ListView 선택
#어떤 템플릿이랑 연결할 것이고, 가져온 오브젝트를 어느 이름으로 mapping 시킬것인지.
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' # index.html에서 이 이름으로 변수에 접근 가능
# 오브젝트 가져오기
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]

DetailView 클래스는 하나의 객체의 세부정보를 보여주므로 generic.DetailView를 상속받아 만들어진다.

'''
def detail(request, question_id): # question_id은 url로 전달받은 값
q = get_object_or_404(Question, pk = question_id) #존재하지 않을 경우 404페이지를 띄움
return render(request, 'polls/detail.html', {'question' : q})

'''
class DetailView(generic.DetailView): # 제네릭뷰의 DetialView를 상속받음
# 어떤 모델이랑 연결해서 어떤 템플릿으로 넘져줄지
model = Question
template_name = 'polls/detail.html'

ResultView 클래스도 하나의 객체의 세부정보를 보여주므로 generic.DetailView를 상속받아 만들어진다.

'''
def results(request, question_id):
question = get_object_or_404(Question, pk = question_id)
return render(request, 'polls/results.html', {'question': question})
'''

class ResultsView(generic.DetailView): # 제네릭뷰의 DetialView를 상속받음
# 어떤 모델이랑 연결해서 어떤 템플릿으로 넘져줄지
model = Question
template_name = 'polls/results.html'

추가적으로 vote메소드의 마지막 라인에서 question_id를 pk로 수정해줘야한다. urlpattern에서 그렇게 수정하였으므로.

#return redirect('polls:results', question_id = question_id)
return redirect('polls:results', pk=question_id)

# generic.DetailView를 상속받은 경우 안보이는 작동원리

- DetailView는 선택된 하나의 객체의 정보에 대해서면 접근할 수 있게 한다.

- 따라서 그 하나의 객체를 식별하기 위해서는 urlpattern에서 pk(primary key)를 하나 무조건 매개변수로 받아야 한다.

- 받은 pk에 해당하는 객체를 클래스 내부에서 지정해준 model에서 가져오는데 이를 연결해준 html에서 모델명의 소문자로 사용할 수 있다.


반응형
Comments