View


๐Ÿ’ก Generic View

Django๋Š” ์›น ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ ์‹œ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋กœ์ง์„ ๋ฏธ๋ฆฌ ๊ฐœ๋ฐœํ•ด๋†“๊ณ 

๊ธฐ๋ณธ ํด๋ž˜์Šค๋กœ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋“ค์„ Generic View๋ผ๊ณ  ํ•œ๋‹ค.

from django.views.generic import ~

ํด๋ž˜์Šคํ˜• ๋ทฐ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํด๋ž˜์Šคํ˜• ์ œ๋„ค๋ฆญ ๋ทฐ๋ฅผ ์ƒ์†๋ฐ›์•„์„œ ํ•„์š”ํ•œ

์†์„ฑ๊ณผ overridingํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.


๐Ÿ“‹ Base View

โ–ช View : ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” ์ตœ์ƒ์œ„ Generic View.

โ–ช TemplateView : ํ…œํ”Œ๋ฆฟ์ด ์ฃผ์–ด์ง€๋ฉด ํ•ด๋‹น ํ…œํ”Œ๋ฆฟ์„ ๋ Œ๋”๋งํ•ด์ค€๋‹ค.

โ–ช RedirectView : URL์ด ์ฃผ์–ด์ง€๋ฉด ํ•ด๋‹น URL๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œ์ผœ์ค€๋‹ค.


๐Ÿ“‹ Generic Display View

โ–ช ListView : ์กฐ๊ฑด์— ๋งž๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช DetailView : ๊ฐ์ฒด ํ•˜๋‚˜์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.


๐Ÿ“‹ Generic Edit View

โ–ช FormView : ํผ์ด ์ฃผ์–ด์ง€๋ฉด ํ•ด๋‹น ํผ์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช CreatView : ํผ์„ ๋ณด์—ฌ์ฃผ๊ณ  ํผ์˜ ๋‚ด์šฉ์œผ๋กœ DB๋ ˆ์ฝ”๋“œ๋ฅผ ์‹ ๊ทœ ์ƒ์„ฑํ•œ๋‹ค.

โ–ช UpdateView : ํผ์„ ๋ณด์—ฌ์ฃผ๊ณ  ํผ์˜ ๋‚ด์šฉ์œผ๋กœ ๊ธฐ์กด DB๋ ˆ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

โ–ช DeleteView : ์‚ญ์ œ ์ปจํŽŒ ํผ์„ ๋ณด์—ฌ์ฃผ๊ณ , ๊ธฐ์กด DB๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•œ๋‹ค.


๐Ÿ“‹ Generic Date View

โ–ช ArchiveIndexView : ์กฐ๊ฑด์— ๋งž๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ์ฒด ๋ฐ ๊ทธ ๊ฐ์ฒด๋“ค์— ๋Œ€ํ•œ ๋‚ ์งœ ์ •๋ณด.

โ–ช YearArchiveView : ์—ฐ๋„๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ๊ทธ ์—ฐ๋„์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช MonthArchiveView : ์—ฐ,์›”์ด ์ฃผ์–ด์ง€๋ฉด ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฑ„๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช WeekArchiveView : ์—ฐ๋„์™€ ์ฃผ๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช DayArchiveView : ์—ฐ,์›”,์ผ์ด ์ฃผ์–ด์ง€๋ฉด ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช TodayArchiveView : ์˜ค๋Š˜ ๋‚ ์งœ์— ํ•ด๋‹นํ•˜๋Š” ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค.

โ–ช DateDetailView : ์—ฐ,์›,์ผ ๊ธฐ๋ณธํ‚ค(๋˜๋Š” ์Šฌ๋Ÿฌ๊ทธ)๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด์˜ ์ •๋ณด ๋ฐ˜ํ™˜.



๐Ÿ“Œ View

๋ชจ๋“  ํด๋ž˜์Šคํ˜• ๋ทฐ์˜ ๊ธฐ๋ณธ์ด ๋˜๋Š” ์ตœ์ƒ์œ„ ๋ทฐ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ํด๋ž˜์Šคํ˜• ๋ทฐ๋Š”

์ด View ํด๋ž˜์Šค๋ฅผ ์ƒ์† ๋ฐ›๋Š”๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์Šค์Šค๋กœ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

class TestView(View):

    def get(self,request,*args,**kwargs):
        return HttpResponse('Hello')

โ–น โœ๐ŸผView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ TemplateView

TemplateView๋Š” ๋‹จ์ˆœํžˆ ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ํ…œํ”Œ๋ฆฟ์— ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ •๋„์˜ ๊ฐ„ํ•œ๋‹จ ๋ทฐ์ด๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
TemplateResponseMixin
ContextMixin
View
from django.views.generic import TemplateView

# views.py
class MainView(TemplateView):
    template_name = 'main/home.html'


# urls.py์— ๋ฐ”๋กœ ์ฝ”๋”ฉํ•  ๋•Œ.
urlpatterns = [
    path('/',TemplateView.as_view(template_name = 'main/home.html'),name='main')
]

โ–น โœ๐ŸผTemplateView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ RedirectView

RedirectView๋Š” ์ฃผ์–ด์ง„ URL๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œ์ผœ์ฃผ๋Š” ์ œ๋„ค๋ฆญ ๋ทฐ๋‹ค.

๊ทธ๋ž˜์„œ URL์†์„ฑ์ด ํ•„์ˆ˜์ด๋‹ค. URL์ด ์—†๋‹ค๋ฉด URL ํŒจํ„ด๋ช…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
View

โ–น โœ๐ŸผRedirectView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ DetailView

DetailView๋Š” ListView์™€ ๋”๋ถˆ์–ด ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์ œ๋„ค๋ฆญ ๋ทฐ์ด๋‹ค.

DetailView๋Š” ํŠน์ • ๊ฐ์ฒด ํ•˜๋‚˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ทฐ์ด๋‹ค.

ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์—์„œ๋Š” object ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์ฝ”๋“œ ์ •๋ณด๋“ค์„ ์ถœ๋ ฅํ•œ๋‹ค.

DetailView๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ…Œ์ด๋ธ”์€ ๋ทฐ ํด๋ž˜์Šค์—์„œ ์ง€์ •ํ•˜๊ณ ,

๋ ˆ์ฝ”๋“œ ๊ฒ€์ƒ‰์šฉ ํ‚ค๋Š” URLconf์—์„œ ์ง€์ •ํ•ด ์ค˜์•ผํ•œ๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
SingleObjectTemplateResponseMixin
TemplateResponseMixin
BaseDetailView
SingleObjectMixin
ContextMixin
View
from django.views.generic import DetailView

class PostDetailView(DetailView):
    model = Post

    # ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    def get_queryset(self):
        qs = super().get_queryset()

        if request.user.is_authenticated:
            qs = qs.filter(is_public=True)
        
        return qs

#-- urls.py
re_path(r'^post/?P<slug>[-w\]+)/$', views.PostDetailView.as_view(),name='detail')

โ–น โœ๐ŸผDetailView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ ListView

LitsView๋Š” ์—ฌ๋Ÿฌ ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ทฐ์ด๋‹ค.

ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์—์„œ๋Š” object_list ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์ฝ”๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
MultipleObjectTemplateResponseMixin
TemplateResponseMixin
BaseListView
MultipleObjectMixin
ContextMixin
View
from django.views.generic import ListView

class PostListView(ListView):
    model = Post
    template_name = 'instagram/post_list.html'
    context_object_name = 'posts' # default : object_list
    paginate_by = 2

โ–น โœ๐ŸผLitsView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ FormView

ํผ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ ์ œ๋„ค๋ฆญ ๋ทฐ์ด๋‹ค. ๊ทธ๋ž˜์„œ ํผ์„ ์ง€์ •ํ•ด์ฃผ๋Š” form_class์™€ ์ด ํผ์„

๋žœ๋”๋งํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ template_name ์†์„ฑ์ด ์ฃผ์š” ์†์„ฑ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ถ”๊ฐ€์ ์œผ๋กœ ํผ

์ฒ˜๋ฆฌ๊ฐ€ ์„ฑ๊ณตํ•œ ํ›„์— ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URL์„ ์ง€์ •ํ•˜๋Š” success_url ์†์„ฑ๋„ ํ•„์š”ํ•˜๋‹ค.โ€™

FormView์˜ ๋™์ž‘ ๋ฐฉ์‹์€ get() ๋ฉ”์†Œ๋“œ์™€ post() ๋ฉ”์†Œ๋“œ์— ๋งž๋Š” ํผ์„ ๋ณด์—ฌ์ค€ ๋‹ค์Œ, ์‚ฌ์šฉ์ž๊ฐ€

ํผ์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์šฉํ•œ์ง€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๊ณ , ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ์ ๋‹นํ•œ ํŽ˜์ด์ง€๋กœ

์ด๋™์„ ํ•˜๋Š” ๋กœ์ง์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
TemplateResponseMixin
BaseFormView
FormMixin
ContextMixin
ProcessFormView
View
from django.views.generic import FormView

class SearchFormView(FormView):
    form_class = SearchForm
    template_name = 'instagram/post_search.html'
    # success_url = 'instagram:post_list'

    def form_valid(self,form):
        word = form.cleaned_data.get('search_word')
        post_list = Post.objects.filter(
                    Q(title__icontains=word) |
                    Q(description__icontains=word) |
                    Q(content__icontains=word))
        context = {
            'form':form,
            'word':word,
            'post_list':post_list,
        }

        return render(self.request, self.template_name, context)

โ–น โœ๐ŸผFormView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ CreateView

CreateView๋Š” ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์„œ ํ…Œ์ด๋ธ”์— ์ €์žฅํ•ด์ฃผ๋Š” ๋ทฐ์ด๋‹ค.

์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ ˆ์ฝ”๋“œ ์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํผ์ด ํ•„์š”ํ•˜๋‹ค.

๊ทธ๋ž˜์„œ CreateView๋Š” FormView์˜ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

CreateView๋Š” ํ•ญ์ƒ ์ž‘์—… ๋Œ€์ƒ์ด ๋˜๋Š” ํ…Œ์ด๋ธ”์ด ์žˆ์œผ๋ฏ€๋กœ,

๊ทธ ํ…Œ์ด๋ธ” ์ •์˜๋กœ๋ถ€ํ„ฐ ํผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
SingleObjectTemplateResponseMixin
TemplateResponseMixin
BaseCreateView
ModelFormMixin
FormMixin
SingleObjectMixin
ContextMixin
ProcessFormView
View
from django.views.generic import CreateView

class PostCreatView(CreatView):
    model = Post

    # ํผ์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•  ํ•„๋“œ ์ •์˜
    fields = []
    
    # ์ƒ์„ฑ ํ›„ ์ด๋™ํ•  URL
    success_url = reverse_lazy('instagram:post_list')

    def form_valid(self,form):
        form.instance.owner = self.request.user
        # ModelFormMixin ํด๋ž˜์Šค์˜ form_valid() ์—์„œ save๋จ.
        return super().form_valid(form)

โ–น โœ๐ŸผCreateView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ UpdateView

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
SingleObjectTemplateResponseMixin
TemplateResponseMixin
BaseUpdateView
ModelFormMixin
FormMixin
SingleObjectMixin
ContextMixin
ProcessFormView
View
#-- views.py
from django.views.generic import UpdateView

class PostUpdateView(UpdateView):
    model = Post
    fields = []
    success_url = reverse_lazy('instagram:post_list')

PostUpdateView = PostUpdateView.as_view()

#-- urls.py
path('<int:pk>/update/', views.PostUpdateView, name='update')

โ–น โœ๐ŸผUpdateView ์†Œ์Šค์ฝ”๋“œ



๐Ÿ“Œ DeleteView

๋ถ€๋ชจ ํด๋ž˜์Šค(MRO)
SingleObjectTemplateResponseMixin
TemplateResponseMixin
BaseDeleteView
DeletionMixin
BaseDetailView
SingleObjectMixin
ContextMixin
View
#-- views.py
from django.views.generic import DeleteView

class PostDeleteView(DeleteView):
    model = Post
    success_url = reverse_lazy('instagram:post_list')

PostDeleteView = PostDeleteView.as_view()

#-- urls.py
path('<int:pk>/delete/', views.PostDeleteView, name='delete')

โ–น โœ๐ŸผDeleteView ์†Œ์Šค์ฝ”๋“œ



GENERIC DATES

GENERIC DATES VIEWobject listdate list
ArchiveIndexView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ)
YearArchiveView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ)๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์›”)
MonthArchiveView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ/์›”)๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์ผ)
WeekArchiveView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ/์ฃผ)๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ)
DayArchiveView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ/์›”/์ผ)๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ)
TodayArchiveView๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์˜ค๋Š˜)๋Œ€์ƒ ๊ฐ์ฒด๋“ค์˜ ๋ฆฌ์ŠคํŠธ(์—ฐ)
DateDetailViewํ•ด๋‹น ๋ณ€์ˆ˜ ์—†์Œํ•ด๋‹น ๋ณ€์ˆ˜ ์—†์Œ


๐Ÿ’ก Generic View Overricing


๐Ÿ“Œ queryset vs get_queryset()

๋‘ ๊ฐœ ๋ชจ๋‘ ์ถœ๋ ฅ ๋Œ€์ƒ์„ ๋ณ€๊ฒฝํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋„์ ์œผ๋กœ ์ถœ๋ ฅ ๋Œ€์ƒ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ธฐ๋Šฅ์€ get_queryset() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


๐Ÿ“Œ get_context_data() ๋ฉ”์†Œ๋“œ

๋ทฐ์—์„œ ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์— ๋„˜๊ฒจ์ฃผ๋Š” ์ปจํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

def get_context_data(self,**kwargs):
    context = super().get_context_data(**kwargs)
    context['SearchWord'] = self.kwargs['word']     # ์ถ”๊ฐ€ 
    return context