알쓸전컴(알아두면 쓸모있는 전자 컴퓨터)

제너릭 뷰 사용하기 본문

Web /Django

제너릭 뷰 사용하기

백곳 2017. 8. 14. 19:35


제너릭 뷰


URL에서 전달 된 매개 변수에 따라 데이터베이스에서 데이터를 가져 오고 이것을 view에서 rander 함수 등을 통해 

템플릿에 리턴하는 기본 웹 개발의 일반적인 경우를 자주 사용하게 되면서 django 에서는 더욱더 적은 코드로 사용할수 있도록 

제너릭 뷰라는 것을 제공합니다. 


대표적인 제너릭 뷰에서 generic.ListView generic.DetailView 가 있습니다.


먼저 views.py를 먼저 보겠습니다.


polls/views.py

from django.shortcuts import get_object_or_404, render

# Create your views here.
from django.http import HttpResponseRedirect,HttpResponse
from .models import Question,Choice
from django.urls import reverse
from django.views import generic
 
def vote(request,question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
	
class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Question.objects.order_by('-pub_date')[:5]

class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'    

polls/urls.py

from django.conf.urls import url
from . import views

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'),
]

urls.py -> DetailView,IndexView,ResultsView 등을 가져오게 하고 


views.py 에서는 class 로 선언하고 generic.ListView or generic.DetailView 을 상속 받아 줍니다. 


Generic Display View

- DetailView: 객체 하나에 대한 상세한 정보를 보여준다.

- ListView: 조건에 맞는 여러 개의 객체를 보여준다


이외에도 여러가지 제너릭 뷰가 있으나 Generic Display View 만 다뤄 보겠습니다. 


ListView

url(r'^$', views.IndexView.as_view(), name='index'),

class IndexView(generic.ListView):

    template_name = 'polls/index.html'

    context_object_name = 'latest_question_list'


    def get_queryset(self):

        """Return the last five published questions."""

        return Question.objects.order_by('-pub_date')[:5]


template_name = 'polls/index.html' 변수에는 템플릿으로 사용할 html 을 넣어 줍니다. 

context_object_name = 'latest_question_list'은 템플릿에 넘겨 줄때 사용할 변수 이름을 지정합니다. 


polls/index.html

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}



DetailView

url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),


question_id -> pk 으로 바뀌 었습니다. 그이유는 


polls/views.py

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

 에서 사용한 pk를 class DetailView 에서도 똑같이 사용할수 있도록 url 로 바로 값을 넣어준것입니다. 


class DetailView(generic.DetailView):

    model = Question

    template_name = 'polls/detail.html'

에서 model 은 상세히 보여줄 모델을 넘겨주는데 템플릿에서는 Question 의 소문자로 하여 변수를 자동 생성하여 탬플릿에서 사용할수 

있게 합니다


polls/detail.html

<h1>{{ question.question_text }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

처럼 model = Question 을 모두 소문자로 바꿔 탬플릿에서 question을 변수로 사용하여 사용할수가 


제너릭 뷰의 기타 종류

  • Base View
    • View: 가장 기본이 되는 최상위 제네릭 뷰
    • TemplateView: 템플릿이 주어지면 해당 템플릿을 렌더링한다.
    • RedirectView: URL이 주어지면 해당 URL로 리다이렉트 시켜준다.
  • Generic Display View
    • DetailView: 객체 하나에 대한 상세한 정보를 보여준다.
    • ListView: 조건에 맞는 여러 개의 객체를 보여준다.
  • Generic Edit View
    • FormView: 폼이 주어지면 해당 폼을 보여준다.
    • CreateView: 객체를 생성하는 폼을 보여준다.
    • UpdateView: 기존 객체를 수정하는 폼을 보여준다.
    • DeleteView: 기존 객체를 삭제하는 폼을 보여준다.
  • Generic Date View
    • YearArchiveView: 년도가 주어지면 그 년도에 해당하는 객체를 보여준다.
    • MonthArchiveView: 월이 주어지면 그 월에 해당하는 객체를 보여준다.
    • DayArchiveView: 날짜가 주어지면 그 날짜에 해당하는 객체를 보여준다.

등이 있습니다.   추후에 필요할때 예제를 찾아서 사용하면 편할것 같습니다. 

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

django css 적용하기  (0) 2017.08.15
DjangoTEST 하기  (0) 2017.08.15
django HttpResponseRedirect 하기  (0) 2017.08.14
django 간단한 폼 만들기  (0) 2017.08.12
dajngo Template 에서 하드코딩된 URL 을 제거  (0) 2017.08.12
Comments