Django Generic View

์•ž์„  ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” HttpResonse, render๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜ํ˜• ๋ทฐ(Function-Based View) ๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ ๊ณผ์ •์—์„œ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋˜๊ณ , ๊ตฌํ˜„์ด ๋ณต์žกํ•ด์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํด๋ž˜์Šค ๋ทฐ(Class-Based View)๊ฐ€ ํ•จ์ˆ˜ํ˜• ๋ทฐ์™€ ๋‹ฌ๋ฆฌ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜๊ณ , ์–ด๋–ค ์žฅ์ ์ด ์žˆ๋Š”์ง€ ์‚ดํŽด ๋ณผ ๊ฒƒ์ด๋‹ค.

Function-Based View

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')

    context = {
        'latest_question_list': latest_question_list,
    }

    return HttpResponse(template.render(context, request))

๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด๋‹ค.

from django.shortcuts import render

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    context = {
        'lastest_question_list': latest_question_list,
    }

    return render(request, 'polls/index.html', context)

render ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. ์œ„์˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•๋ณด๋‹ค๋Š” ๋” ๊ฐ„๋‹จํ•ด์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. template ์ฝ”๋“œ ๋ถ€๋ถ„์ด ์—†์–ด์ง€๊ณ , render๋กœ ๋ฐ”๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Class-based View

Class-Based View ์‚ฌ์šฉ ๊ฐ€์ด๋“œ๋ผ์ธ

  • ๋ทฐ๋Š” ๊ฐ„๋‹จ ๋ช…๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

  • ๋ทฐ ์ฝ”๋“œ์˜ ์–‘์€ ์ ์œผ๋ฉด ์ ์„์ˆ˜๋ก ์ข‹๋‹ค.

  • ๋ทฐ ์•ˆ์—์„œ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋ทฐ๋Š” ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๋กœ์ง์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ๋ชจ๋ธ์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋งค์šฐ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ์—๋งŒ ํผ์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • 403, 404, 500 ์—๋Ÿฌ ํ•ธ๋“ค๋ง์—๋Š” CBV๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  FBV๋ฅผ ์ด์šฉํ•œ๋‹ค.

  • ๋ฏน์Šค์ธ์€ ๊ฐ„๋‹จ๋ช…๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

Generic Views

์œ„์˜ ํ•จ์ˆ˜ํ˜• ๋ทฐ์—์„œ ๋ฐ˜๋ณต๋˜๋Š” ๋ถ€๋ถ„์„ ํŒจํ„ดํ™”ํ•˜์—ฌ์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์ถ”์ƒํ™” ํ•˜์˜€๋‹ค. Generic View๋Š” ์›น ๊ฐœ๋ฐœ์‹œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์žฅ๊ณ ์—์„œ ๋ฏธ๋ฆฌ ์ œ๊ณตํ•ด์ค€๋‹ค.

from django.views import generic

class IndexView(generic.ListView):
    model = Question

์œ„์™€ ๊ฐ™์ด ์ตœ์†Œํ•œ ๊ทธ ๋ทฐ๊ฐ€ ์–ด๋–ค ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€๋งŒ ์ง€์ •ํ•ด์ฃผ๋ฉด generic view๊ฐ€ ๋ชจ๋“ ๊ฑธ ์•Œ์•„์„œ ํ•ด์ค€๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ๊ฐ ๋ทฐ๋งˆ๋‹ค ๋‹ฌ๋ผ์ง€๋Š” ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด๋œ๋‹ค. Class-based View๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ๋‹ค.

  • GET, POST๋“ฑ HTTP ๋ฉ”์†Œ๋“œ์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ ์ž‘์„ฑ์‹œ ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๊น”๋”ํ•ด์ง„๋‹ค. ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง„๋‹ค.

  • ๋‹ค์ค‘์ƒ์† ๊ฐ™์€ ๊ฐ์ฒด์ง€ํ–ฅ ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•ด ์ œ๋„ˆ๋ฆญ ๋ทฐ, ๋ฏน์Šค์ธ ํด๋ž˜์Šค ๋“ฑ์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ๊ณผ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.

  • ๋ณต์žกํ•œ ๊ตฌํ˜„์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

ํ•˜์ง€๋งŒ ํด๋ž˜์Šคํ˜• ๋ทฐ๊ฐ€ ํ•จ์ˆ˜ํ˜• ๋ทฐ๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์ƒํ™ฉ์— ๋”ฐ๋ผ ์„ ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์ง€ ์–ด๋Š ํ•œ์ชฝ์ด ๋” ์ข‹๋‹ค๊ณ  ๋งํ•˜๊ธฐ๋Š” ์–ด๋ ต๋‹ค.

Generic View๋Š” from django.views import generic ์™ธ๋ถ€ ๋ชจ๋“ˆ ์ ์šฉ์ด ํ•„์š”ํ•˜๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Base View : ๋ทฐ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‹ค๋ฅธ ์ œ๋„ˆ๋ฆญ ๋ทฐ์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ๋˜๋Š” ๊ธฐ๋ณธ ๋ทฐ

    • View : ์ตœ์ƒ์œ„ ๋ถ€๋ชจ ์ œ๋„ˆ๋ฆญ ๋ทฐ ํด๋ž˜์Šค

    • TemplateView : ์ฃผ์–ด์ง„ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋ Œ๋”๋ง

    • RedirectView : ์ฃผ์–ด์ง„ URL๋กœ redirect

  • Genreic Display View : ๊ฐ์ฒด์˜ ๋ชฉ๋ก ๋˜๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด ์ƒ์„ธ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ทฐ

    • DetailView : ์กฐ๊ฑด์— ๋งž๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด ์ถœ๋ ฅ

    • ListView : ์กฐ๊ฑด์— ๋งž๋Š” ๊ฐ์ฒด ๋ชฉ๋ก ์ถœ๋ ฅ

  • Generic Edit View : Form์„ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋ทฐ

    • FormView : ํผ์ด ์ฃผ์–ด์ง€๋ฉด ํ•ด๋‹น ํผ์„ ์ถœ๋ ฅ

    • CreateView : ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํผ ์ถœ๋ ฅ

    • UpdateView : ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ํผ ์ถœ๋ ฅ

    • DeleteView : ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•˜๋Š” ํผ ์ถœ๋ ฅ

  • Generic Date View : ๋‚ ์งœ ๊ธฐ๋ฐ˜ ๊ฐ์ฒด์˜ ์—ฐ/์›”/์ผ ํŽ˜์ด์ง€๋กœ ๊ตฌ๋ถ„ํ•ด ๋ณด์—ฌ์ฃผ๋Š” ๋ทฐ

    • YearArchiveView: ์ฃผ์–ด์ง„ ์—ฐ๋„์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ถœ๋ ฅ

    • MonthArchiveView: ์ฃผ์–ด์ง„ ์›”์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ถœ๋ ฅ

    • DayArchiveView: ์ฃผ์–ด์ง„ ๋‚ ์งœ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ถœ๋ ฅ

    • TodayArchiveView: ์˜ค๋Š˜ ๋‚ ์งœ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ถœ๋ ฅ

    • DateDetailView: ์ฃผ์–ด์ง„ ์—ฐ, ์›”, ์ผ PK(๋˜๋Š” ์Šฌ๋Ÿฌ๊ทธ)์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ถœ๋ ฅ

์˜ˆ์ œ

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.views import generic
# from django.template import loader
# from django.http import Http404

from .models import Question

# Create your views here.
class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        return Question.objects.order_by('-pub_date')[:6]
  """๊ธฐ๋ณธ ๋ทฐ(View, Template, RedirectView) 3๊ฐœ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ชจ๋“  ์ œ๋„ˆ๋ฆญ ๋ทฐ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. 
  ๋””ํดํŠธ๋Š” queryset ์†์„ฑ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 
  queryset ์†์„ฑ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ชจ๋ธ ๋งค๋‹ˆ์ € ํด๋ž˜์Šค์˜ all() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ    ์ถœํ•ด QuerySet ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ๋ฐ˜ํ™˜ํ•œ๋‹ค."""

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

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

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):
        return render(request, 'polls/detail.html', {'question' : question, 'error_message':"You didn't select a choice"})
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

์ฐธ๊ณ 

Last updated