The view layer - The basics: View functions

서경원·2024년 4월 5일

django

목록 보기
1/1

view는 파이썬 함수이다.
views.py는 앱 내 또는 프로젝트에 위치한다.
views.py 파일 내 어디든 view 코드를 두면 된다.

응답(response)

  • HTML contents
  • redirect
  • 404 error
  • XML 문서
  • 이미지
  • ... 등등

을 함으로써 페이지를 띄울 수 있다.

A simple view

from django.http import HttpResponse
import datetime


def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

Mapping URLs to views

URL dispatcher를 통해 view와 특정 url을 연결짓고 관리할 수 있다.

Returnig errors

  • 장고는 HTTP error code를 반환하는 HttpResponse 하위 클래스가 있다.
from django.http import HttpResponse, HttpResponseNotFound


def my_view(request):
    # ...
    if foo:
        return HttpResponseNotFound("<h1>Page not found</h1>")
    else:
        return HttpResponse("<h1>Page was found</h1>")
  • status를 지정해 줄 수도 있음.
from django.http import HttpResponse


def my_view(request):
    # ...

    # Return a "created" (201) response code.
    return HttpResponse(status=201)

The Http404 exception

  • 404 에러는 가장 흔한 에러이기 때문에 그 에러를 다루는 더 쉬운 방법이 있습니다.

class django.http.Http404

  • 기본적으로 HTML의 에러 페이지를 반환할 수 있다.
return HttpResponseNotFound("<h1>Page not found</h1>")
  • 더 쉬운 방법으로 Http404를 쓰는 방법이 있다. 장고가 앱에 발생한 404에러를 캐치해 standard 404에러를 반환해 준다.
from django.http import Http404
from django.shortcuts import render
from polls.models import Poll


def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, "polls/detail.html", {"poll": p})

DEBUG가 True이면 메세지가 http404에게 제공되고 standard 404 debug template에 나타난다.
디버그 과정에서 이 메세지를 사용하면 좋다. 그리고 일반적으로 production 환경에서는 사용하지 않는다.

Customizing error view

The page_not_found() view is overridden by handler404:
handler404 = "mysite.views.my_custom_page_not_found_view"

The server_error() view is overridden by handler500:
handler500 = "mysite.views.my_custom_error_view"

The permission_denied() view is overridden by handler403:
handler403 = "mysite.views.my_custom_permission_denied_view"

The bad_request() view is overridden by handler400:
handler400 = "mysite.views.my_custom_bad_request_view"

CSRF 에러 view를 override해서 CSRF_FAILURE_VIEW를 사용할 수도 있다!
Cross-Site Request Forgery (CSRF)

Testing custom error views

from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings
from django.urls import path


def response_error_handler(request, exception=None):
    return HttpResponse("Error handler content", status=403)


def permission_denied_view(request):
    raise PermissionDenied


urlpatterns = [
    path("403/", permission_denied_view),
]

handler403 = response_error_handler


# ROOT_URLCONF must specify the module that contains handler403 = ...
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorHandlerTests(SimpleTestCase):
    def test_handler_renders_template_response(self):
        response = self.client.get("/403/")
        # Make assertions on the response here. For example:
        self.assertContains(response, "Error handler content", status_code=403)
  • @override_settings(ROOT_URLCONF=__name__)
    • 이 오버라이드 세팅은 root urlconf를 __name__으로 설정한다.
      • __name__은 파이썬에서 해당 파일(모듈)을 가리킨다.
      • 전역적으로 설정되어 있는 urls.py 대신 테스트 하는 동안 현재 파일에 있는 urlpatterns를 적용시킬 수 있다.
      • 일반적으로 테스트를 하기 위해선 python manage.py test를 사용하고 test 파일은 TestCase 등의 테스트를 위한 클래스를 상속받아서 작성하면 장고가 알아서 test파일을 찾아서 실행하고 결과를 반환한다.

Async views

  • views는 동기 함수일뿐만 아니라 파이썬에 정의된 async def를 사용해 비동기 함수가 될 수도 있다.
  • 장고는 비동기 context를 자동으로 탐색하지만 비동기의 제 성능을 내려면 ASGI(Asycronous Server Gateway Interface)를 사용해야 한다.
import datetime
from django.http import HttpResponse


async def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
profile
멋진 사나이

0개의 댓글