ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Day-1(Templates, get_context_data)
    TIL & Todo List/Coding for Entrepreneures 2020. 1. 12. 23:42

    기본 Model & View 설정

    • 동영상은 youtube에서 '공유-퍼가기(iframe tag로 구성된 url)'를 이용 - embed_code 필드에 입력된다.

    models.py

    from django.db import models
    
    
    # Create your models here.
    class Video(models.Model):
        title = models.CharField(max_length=120)
        embed_code = models.TextField()
        timestamp = models.DateTimeField(auto_now_add=True)
        updated = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return self.title
    

    view.py - CRUDL을 구성하기 위한 기본 View 구성

    # CRUDL
    from django.views.generic import CreateView, DetailView, ListView, UpdateView, DeleteView
    
    class VideoCreateView(CreateView):
        queryset = Video.objects.all()
    	
    
    class VideoDetailView(DetailView):
        queryset = Video.objects.all()
    
    
    class VideoListView(ListView):
        queryset = Video.objects.all()
    
    
    class VideoUpdateView(UpdateView):
        queryset = Video.objects.all()
    
    
    class VideoDeleteView(DeleteView):
        queryset = Video.objects.all()
    • generic 기반 Views에 render_to_response(HttpResponse를 담고 있는 메서드)를 포함하기 때문에 별도의 반환값을 지정하지 않아도 된다. Http Method(get, post, put 등..)를 처리할 때, 기능을 추가하거나 변경하고자 할 경우 오버라이딩하는 과정에서 반드시 HttpResponse, render 또는 render_to_response로 반환해야 한다.
    • view에서 자주 사용하는 render(django.shortcuts.render) 메서드는 아래와 같이 템플릿, 컨텍스트 등을 HttpResponse에 담아 반환한다.
    # django.shortcuts.render
    
    def render(request, template_name, context=None, content_type=None, status=None, using=None):
        """
        Return a HttpResponse whose content is filled with the result of calling
        django.template.loader.render_to_string() with the passed arguments.
        """
        content = loader.render_to_string(template_name, context, request, using=using)
        return HttpResponse(content, content_type, status)
    

    HttpResponse

    페이지를 표시할 때 HttpResonse 객체를 요구한다. 없을경우 ValueError 발생.

    HttpResonse 객체를 반환하라는 에러 메세지 - ValueError

     

    Templates - settings

    # settings.py
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    • BASE_DIR: 프로젝트의 root 폴더(manage.py가 위치한) 디렉토리
    • DIRS: 프로젝트에서 사용될 템플릿의 위치를 지정한다. 위와 같이 구성할 경우 root폴더에 위치한 templates 폴더에 템플릿 파일을 위치시켜야 한다.
      • APP_DIRS보다 높은 우선순위를 갖는다.
    • APP_DIRS: 각 apps에서 템플릿을 검색할지 여부
      • APP_DIRS=True일 경우, template engine에 의해 app에서 사용될 templates 폴더를 해당 app 내에서 검색한다. 일반적으로 templates 하위 폴더에 app의 이름으로 된 폴더를 위치 시킨다.(예: index.html 위치: myapps.templates.myapps.index.html)
        • generics.view를 사용할 경우 뷰에 사용되는 모델 이름(Video)과 동작 메서드(list, update, delete, ...)를 접미어로 사용하여 한 번 더 검색
        • 예) class VideoListView(ListView) -> video_list
        • class VideoUpdateView(UpdateVIew) -> video_update

    root directory에서 video_list.html을 검색

    • 템플릿을 자동으로 검색(아래의 abc directory는 없다고 생각하자)

    template.loaders는 root directory에 위치한 abc/templates에서 먼저 index.html을 검색하고(첫 번째), videos앱에 있는 template/videos에 index.html을 검색한다(네 번째). -> 찾지 못할 경우 에러 

    • OPTIONS - context_processors: context_processor.request & auth는 템플릿에서 request와 user에 대한 처리를 가능토록 지원한다.
    <h1>Hello, {{ name }}!</h1>
    <p>request: {{ request }}</p>
    <p>auth: {{ user }}</p>

    <name>은 view에서 전달된 context, request와 auth는 settings에 설정된 context_processor에서 잔달된 context

     

    Generic view - get_context_data

    generic view에서 context를 templates에 전달할 경우 get_context_data 메서드를 오버라이딩 한다.

    - render의 매개변수에 context를 담아 templates에 전달하는 것을 get_context_data에서 처리한다.

    class VideoListView(ListView):
        queryset = Video.objects.all()
    
        def get_context_data(self, *, object_list=None, **kwargs):
            context = super(VideoListView, self).get_context_data(**kwargs)
            print(context)
            return context
            
    # output
    {'paginator': None, 'page_obj': None, 'is_paginated': False, 'object_list': <QuerySet 
    [<Video: django 2.2>, <Video: django 1.11>]>, 'video_list': <QuerySet [<Video: django 2.2>, <Video: django 1.11>]>, 
    'view': <videos.views.VideoListView object at 0x106292cc0>}
    
    

    - super(VideoListView, self).get_context_data(**kwargs): VideoListView의 상위 클래스(ListView)의 get_context_data를 불러오고 이를 반환

    - 상위 클래스의 get_context_data에는 template에 필요한 몇 가지 변수들을 담고 있다(paginator, object_list 등...).

    - 실제 코드에서는 불러온 값에 일부 context값을 추가하여 반환한다.

     

    {{ block.super }}: 부모(extends) 템플릿에 있는 해당 블록의 값을 가져온다.

    # base.html
    {% block title %}
    	Srvup
    {% endblock %}
    
    
    # video_list.html
    {% extends 'base.html'%}
    {% block title %}
    	Video | {{ block.super }}
    {% endblock %}

    왼쪽은 video_list의 title, 오른쪽은 base의 title

     

    댓글

Designed by Tistory.