2010/8/2 Django Robot
<djangomailsender-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Olá a todos!
Tenho a seguinte dúvida: estou verificando se alguns dados existem no
banco de dados usando:
teste = get_object_or_404(Tabela, laranja='madura')
teste = Tabela.objects.get(laranha='madura')
A primeira retorna página 404 e a segunda um erro informado pelo
django, pois não existem laranjas maduras.
A questão é: Qual a necessidade de uma ou outra? Vejo ambas inúteis
para o cliente final, já que não quero que apresente erro algum. E
para não aparecer eu teria que usar:
try:
teste = get_object_or_404(Tabela, laranja='madura')
return HttpResponse("laranja encontrada")
except:
return HttpResponse("não foi encontradas laranjas maduras")
Não há nenhum jeito melhor de retornar isso? se não encontrar nada
apenas teste = False e pronto?
São várias questões aqui:
1. Se o usuário acessa uma URL que aponta para um recurso (Laranjas) que não existe
o correto é retornar um erro HTTP 404 (Not Found). É assim que o HTTP e, consequentemente,
a Web funcionam. Quer você queira ou não. A mensagem exibida na sua página 404 pode
(deve?) ser personalizada para ficar "ao gosto do freguês" mas o código de retorno HTTP deve
ser 404.
2. A função get_object_or_404() é um atalho para o código:
try:
obj = Tabela.get(pk=1)
except Tabela.DoesNotExist:
raise Http404("...")
3. Não tenha medo de usar o sistema de exceções do Python. O modo "pythonico" de lidar com
uma exceção (ex. acessar um objeto que não existe) é com try/except e não com 'if ...'. Então o
código acima é melhor do que:
objs = Tabela.filter(pk=1)
if not objs:
raise Http404() # ou incorretamente fazer return HttpResponse("erro")
... esse modo de trabalhar é usado em linguagens de programação sem suporte a tratamento de
exceções ou com um suporte limitado/mal-implementado.
Valeu,
Osvaldo
tipo:
teste = get_object_or_False(Tabela, laranja='madura')
if teste:
return HttpResponse("laranja encontrada")
else:
return HttpResponse("não foi encontradas laranjas maduras")
Vejo mais vantagens utilizando assim pois quando começa a ter vários
try dentro try, o código começa a ficar sujo, já não sabe as vezes da
onde vem o erro. Se retornasse apenas false eu ainda poderia utilizar
a variável para outras coisas também.
O que você diz sobre "não saber de onde vem o erro" frequentemente é resultado
do tratamento incorreto das exceções. Pessoas que fazem:
try:
...
except:
print "erro!"
ou ainda...
try:
...
except Exception:
print "deu pau!"
estão fazendo esse tratamento da forma errado. Você deve tratar as exceções de nível mais alto
possível (considerando (Base)Exception a exceção de nível mais baixo) e *somente* aquelas
exceções que você saiba tratar (ex. tentar acessar um objeto inexistente deve retornar um erro
404 para o cliente).
No meu blog eu escrevi algumas dicas sobre isso e sobre algumas outras coisas:
Valeu,
Osvaldo