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.
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ódulo django.http, também a biblioteca datetime do Python.
Depois, nós definimos uma função chamada current_datetime. Esta é a função view. Cada função view recebe um objeto HttpRequest como seu primeiro parâmetro, que é tipicamente nomeado como request.
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 objeto HttpResponse. (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.
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.
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.
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.
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:
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.
Dec 26, 2011