(page_model_recipes)= # 레시피 ## {meth}`~wagtail.models.Page.serve` 메서드 재정의 Wagtail은 {class}`~wagtail.models.Page` 에서 파생된 모델을 모델 이름과 일치하는 Django HTML 템플릿에 페이지 객체에 대한 참조를 전달하여 제공하는 것을 기본으로 하지만, HTML 이외의 것을 제공하고 싶다면 어떻게 해야 할까요? {class}`~wagtail.models.Page` 클래스에서 제공하는 {meth}`~wagtail.models.Page.serve` 메서드를 재정의하고 Django 요청 및 응답을 더 직접적으로 처리할 수 있습니다. `EventPage` 객체의 다음 예시를 고려해 봅시다. 이 객체는 요청에 `format` 변수가 설정된 경우 iCal 파일로 제공됩니다. ```python class EventPage(Page): ... def serve(self, request): if "format" in request.GET: if request.GET['format'] == 'ical': # ical 형식으로 내보내기 response = HttpResponse( export_event(self, 'ical'), content_type='text/calendar', ) response['Content-Disposition'] = 'attachment; filename=' + self.slug + '.ics' return response else: # 인식할 수 없는 형식 오류 message = '이벤트를 내보낼 수 없습니다.\n\n인식할 수 없는 형식: ' + request.GET['format'] return HttpResponse(message, content_type='text/plain') else: # 평소와 같이 이벤트 페이지 표시 return super().serve(request) ``` {meth}`~wagtail.models.Page.serve` 는 Django 요청 객체를 받아 Django 응답 객체를 반환합니다. Wagtail은 템플릿과 생성하는 컨텍스트를 포함하는 `TemplateResponse` 객체를 반환하며, 이는 미들웨어가 의도한 대로 작동하도록 합니다. 따라서 `HttpResponse` 와 같은 더 간단한 응답 객체는 이러한 이점을 얻지 못한다는 점을 명심하십시오. 이 전략을 사용하면 Django 또는 Python 유틸리티를 사용하여 모델을 JSON 또는 XML 또는 원하는 다른 형식으로 렌더링할 수 있습니다. (overriding_route_method)= ## 사용자 지정 {meth}`~wagtail.models.Page.route` 메서드로 엔드포인트 추가 ```{note} 페이지에 더 많은 엔드포인트를 추가하는 훨씬 더 간단한 방법은 [](routable_page_mixin) 믹스인에서 제공합니다. ``` Wagtail은 경로 구성 요소(슬래시 `/` 로 구분됨)를 반복하고, 슬러그를 기반으로 일치하는 객체를 찾고, 해당 객체의 모델 클래스에 추가 라우팅을 위임하여 요청을 라우팅합니다. Wagtail 소스는 어떤 일이 발생하는지 파악하는 데 매우 유용합니다. 다음은 `Page` 클래스의 기본 `route()` 메서드입니다. ```python class Page(...): ... def route(self, request, path_components): if path_components: # 요청은 이 페이지의 자식에 대한 것입니다. child_slug = path_components[0] remaining_components = path_components[1:] # 일치하는 자식을 찾거나 404 try: subpage = self.get_children().get(slug=child_slug) except Page.DoesNotExist: raise Http404 # 추가 라우팅 위임 return subpage.specific.route(request, remaining_components) else: # 요청은 이 페이지 자체에 대한 것입니다. if self.live: # 이 페이지의 serve() 메서드를 호출하도록 Wagtail에 알리는 RouteResult 반환 return RouteResult(self) else: # 페이지가 요청과 일치하지만 게시되지 않았으므로 404 raise Http404 ``` {meth}`~wagtail.models.Page.route` 는 현재 객체(`self`), `request` 객체, 그리고 요청 URL에서 남은 `path_components` 목록을 받습니다. Wagtail 트리에서 자식 중 하나에 대해 {meth}`~wagtail.models.Page.route` 를 다시 호출하여 라우팅을 계속 위임하거나, `RouteResult` 객체를 반환하거나 404 오류를 발생시켜 라우팅 프로세스를 종료합니다. {meth}`~wagtail.models.Page.route` 메서드를 재정의하여 Wagtail 트리에서 각 객체에 대한 사용자 지정 엔드포인트를 만들 수 있습니다. 한 가지 사용 사례는 경로에서 `print/` 엔드포인트를 만날 때 대체 템플릿을 사용하는 것입니다. 다른 사용 사례는 현재 객체와 상호 작용하는 REST API일 수 있습니다. 어떤 일이 발생하는지 확인하기 위해 모든 자식 경로 구성 요소를 인쇄하는 간단한 모델을 만들어 보겠습니다. 먼저 `models.py`: ```python from django.shortcuts import render from wagtail.url_routing import RouteResult from django.http.response import Http404 from wagtail.models import Page # ... class Echoer(Page): def route(self, request, path_components): if path_components: # Wagtail에 self.serve()를 추가 'path_components' kwarg와 함께 호출하도록 알립니다. return RouteResult(self, kwargs={'path_components': path_components}) else: if self.live: # Wagtail에 self.serve()를 추가 인수 없이 호출하도록 알립니다. return RouteResult(self) else: raise Http404 def serve(self, path_components=[]): return render(request, self.template, { 'page': self, 'echo': ' '.join(path_components), }) ``` 이 모델 `Echoer` 는 속성을 정의하지 않지만 `Page` 를 서브클래스하므로 객체는 사용자 지정 제목과 슬러그를 가질 수 있습니다. 템플릿은 `{{ echo }}` 속성을 표시하기만 하면 됩니다. 이제 Wagtail 관리자에서 "Echo Base"라는 새 `Echoer` 페이지를 만든 후 다음과 같은 요청은: ``` http://127.0.0.1:8000/echo-base/tauntaun/kennel/bed/and/breakfast/ ``` 다음을 반환합니다. ``` tauntaun kennel bed and breakfast ``` `serve()` 메서드에 새로운 필수 인수를 도입하는 경우 주의하십시오. Wagtail은 미리 보기 및 중재를 위해 페이지의 기본 뷰를 계속 표시할 수 있어야 하며, 기본적으로 요청 객체와 추가 인수 없이 `serve()` 를 호출하여 이 작업을 수행하려고 시도합니다. `serve()` 메서드가 이를 메서드 시그니처로 허용하지 않으면 페이지의 `serve_preview()` 메서드를 재정의하여 적절한 인수로 `serve()` 를 호출해야 합니다. ```python def serve_preview(self, request, mode_name): return self.serve(request, variant='radiant') ```