Escrevendo Views¶
Uma função view, ou somente view, é simplesmente uma função Python que recebe
uma requisição Web e retorna uma resposta Web. Esta resposta pode ser um
conteúdo HTML de uma página, ou um redirecionamento, ou um erro 404, ou um
documento XML, ou uma imagem . . . ou qualquer coisa, na verdade. O view em si
contém qualquer lógica arbitrária que é necessária para retornar uma resposta.
Este código pode ficar em qualquer lugar que você quiser, ao longo do seu Python
path. Não há outro requerimento – sem “mágica”, por assim dizer.
Por uma questão de colocar o código “em qualquer lugar”, vamos criar um arquivo
chamado views.py
no diretório mysite
, que você criou no capítulo
anterior.
Um view simples¶
Aqui há um view que retorna a data atual, como um documento HTML:
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)
Vamos passo-a-passo através deste código, uma linha por vez:
Primeiro, nós importamos a classe
HttpResponse
, que reside o módulodjango.http
, também a bibliotecadatetime
do Python.Depois, nós definimos uma função chamada
current_datetime
. Esta é a função view. Cada função view recebe um objetoHttpRequest
como seu primeiro parâmetro, que é tipicamente nomeado comorequest
.Note que o nome da função view não importa; ele não tem de ser nomeada de uma certa forma para ser reconhecida pelo Django. Nós estamos chamando-a de
current_datetime
aqui, porque este nome indica claramente o que ela faz.O view retorna um objeto
HttpResponse
que contém a resposta gerada. Cada função view é responsável por retornar um objetoHttpResponse
. (Há exceções, mas serão abordadas mais tarde.)
Django’s Time Zone
O Django inclui uma configuração de TIME_ZONE
que por padrão é
America/Chicago
. Este provavelmente não é onde você mora, então você
pode mudá-lo no seu arquivo settings.py
.
Mapeando URLs para Views¶
Então, para recapitular, esta função view retorna uma página HTML, que inclui a data e hora atual. Para mostrar este view numa URL em particular, você precisará criar uma no URLconf; veja URL dispatcher para instruções.
Retornando erros¶
Retornar códigos de erro HTTP no Django é muito fácil. Existem subclasses do
HttpResponse
para um número de códigos de status comuns do
HTTP além do 200 (que significa “OK”). Você pode encontrar a lista completa de
subclasses disponíveis na documentação de requisição/resposta. Somente retorne um instância de uma destas
subclasses ao invés de uma classe normal HttpResponse
a
fim de mostrar um erro. Por exemplo:
def my_view(request):
# ...
if foo:
return HttpResponseNotFound('<h1>Page not found</h1>')
else:
return HttpResponse('<h1>Page was found</h1>')
Não existe uma subclasse especializada para cada código resposta HTTP possível,
uma vez que muitos deles não serão comuns. Porém, como documentado na
documentação do HttpResponse
, você também pode passar o
código de status HTTP dentro de um construtor do
HttpResponse
para criar uma classe de retorno para
qualquer código de status que você quiser. Por exemplo:
def my_view(request):
# ...
# Retorna um código de resposta "created" (201).
return HttpResponse(status=201)
Como erros 404 são de longe os erros HTTP mais comuns, existe uma forma mais fácil de manipular estes erros.
A exceção Http404¶
Quando você retorna um erro como HttpResponseNotFound
, você é responável por
definir o HTML da página de erro resultante:
return HttpResponseNotFound('<h1>Page not found</h1>')
Por convenção, e porque é uma boa idéia ter uma página de erro 404 consistente
para todo site, o Django provê uma exceção Http404
. Se você lançar um
Http404
em qualquer ponto de sua função view, o Django a pegará e retornará
a página de erro padão para sua aplicação, junto com o código de erro HTTP 404.
Example usage:
from django.http import Http404
def detail(request, poll_id):
try:
p = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise Http404
return render_to_response('polls/detail.html', {'poll': p})
A fim de usar a exceção Http404
para sua satisfação, você deve criar um
template que será mostrado quando um erro 404 é gerado. Este template deve ser
chamado 404.html
e localizado no nível mais alto de sua árvore de templates.
Customizando erros de views¶
O view 404 (page not found)¶
Quando você gera uma exceção Http404
, o Django carrega um view especial
devotado a manipular erros 404. Por padrão, ele é o view
django.views.defaults.page_not_found
, que carrega e renderiza o template
404.html
.
Isto significa que você precisa definir um template 404.html
na raiz do seu
diretório de templates. Este template será usado para todos os erros 404.
Esta view page_not_found
deve bastar para 99% das aplicações Web, mas se
você precisa sobrescrevê-lo, você pode especificar handler404
no seu
URLconf, desta forma:
handler404 = 'mysite.views.my_custom_404_view'
Por trás das cenas, o Django obriga o view 404 a procurar por handler404
.
Por padrão, os URLconfs contém as seguinte linha:
from django.conf.urls.defaults import *
Que se preocupa com a configuração do handler404
no módulo atual. Como você
pode ver em django/conf/urls/defaults.py
, handler404
é setado para
'django.views.defaults.page_not_found'
por padrão.
Three things to note about 404 views:
- O view 404 é também chamado se o Django não encontrar uma combinação depois de checar todas as expressões regulares no URLconf.
- Se você não definir se próprio view 404 – e simplesmente usar o padrão,
o que é recomendado – você ainda tem uma obrigação: você deve criar um
template
404.html
na raiz do seu diretório de templates. Por padrão, o view 404 usará este template para todos os erros 404. Por padrão, o view 404 passará uma variável para o template:request_path
, que é a URL que resultou no erro 404. - Ao view 404 é passado um
RequestContext
e terá acesso a variáveis fornecidas por sua configuraçãoTEMPLATE_CONTEXT_PROCESSORS
(e.g.,MEDIA_URL
). - Se
DEBUG
é setado comoTrue
(no seu módulo settings), então seu view 404 nunca será usado, e o traceback será mostrado no lugar dele.
O view 500 (server error)¶
Similarmente, o Django executa um comportamente especial no caso de um erro de
execução no código do view. Se um view resulta num exceção, o Djanto irá, por
padrão, chamar o view django.view.defaults.server_error
, que carrega e
renderiza o template 500.html
.
Isto significa que você precisa definir um template 500.html
na raiz do seu
diretório de templates. Este template será usado para todos os erros de
servidor. O view 500 padrão não passa variáveis para este template e é
renderizado com um Context
vazio para reduzir as chances de erros
adicionais.
Este view server_error
deve bastar para 99% das aplicações Web, mas se você
quiser sobrescrever o view, você pode especificar handler500
no seu URLconf,
desta forma:
handler500 = 'mysite.views.my_custom_error_view'
Por trás das cenas, o Django obriga o view de erro a prcurar pelo
handler500
. Por padrão, os URLconfs contém a seguinte linha:
from django.conf.urls.defaults import *
Que se preocupa de setar handler500
no módulo atual. Como você pode ver em
django/conf/urls/defaults.py
, handler500
é setado para
'django.views.defaults.server_error'
por padrão.