Django Wars [Parte 23]: Melhorando o redirect() e o urls.py

O Django Wars foi idealizado e desenvolvido no Django 1.4. Algumas funcionalidades aqui descritas podem não funcionar ou funcionar de forma diferente em outras versões do Django

Em algumas das views do projeto, utilizamos a função redirect().
Enquanto estivemos descrevendo todas as views em um único arquivo views.py, estivemos passando como parâmetros nas chamadas da função redirect() os métodos das views para as quais desejavamos redirecionar.
Neste modo, o Django pega a view, procura a url dela no arquivo urls.py e redireciona.
Porém, como mudamos tudo e agora temos várias views em vários arquivos diferentes, manter essa tática pode quebrar o projeto.
Estamos correndo o perido de sofrer de Circular Imports (imports circulares).

Isso ocorre quando um módulo A importa o módulo B, e o módulo B importa o módulo A.
No processamento Python, ocorre mais ou menos assim:
Pega o arquivo do moduloA.py e processa-o.
Neste arquivo encontra o import do moduloB.py.
Para o processamento de moduloA.py para carregar e processar o moduloB.py.
Ao processar o moduloB.py percebe que este carrega o moduloA.py.
E ai, o Python poderia entrar em loop infinito e explodir o mundo! (não tão grave assim)
Mas o que o Python faz é ver se moduloA está na memória antes de importá-lo.
Como ele está na memória, retorna para o moduloB.py o que está lá.
A bronca é que o que o Python tem naquela hora é só um pedaço do carregamento do moduloA.py.
E ai, se dentro do funcionamento de moduloB.py fizer uma chamada para algo de moduloA.py que ainda não foi carregado, PAU!

Para fugir disso, a coisa mais fácil a se fazer é alterar um pouco o funcionamento do urls.py.
O que vamos fazer é dar nomes as urls.
Na descrição do módulo django.conf.urls vemos como escrever urls bem supimpas.
Mas, para ficar de fácil entendimento como devemos proceder, vou colocar aqui o urls.py modificado.

Notem que não dei nomes a todas as urls, apenas as urls principais (linhas 17, 18, 20, 24, 30).

Agora, para ser feliz, basta alterar as chamadas da função redirect nas views que a utilizam para, ao invés de se referenciarem através do método da view, utilizarem o nome da url.
Para elucidar o que deve ser feito, vou alterar o arquivo views/player.py

Primeiro, na parte dos imports, removi todos os imports para qualquer outra view.
Na linha 38, alterei a chamada de redirect() para receber o nome da url e não o método que recebia antes.

Notem que na linha 20 não alterei a chamada de redirect().
Como o método chamado, logar, está neste mesmo arquivo, optei por não mudar para ficar de aprendizado que o redirect() possui mais de uma forma de funcionar.

Por fim, farei as alterações em todos os outros arquivos dentro da pasta views.
Espero que vocês façam as alterações nos arquivos de vocês, ou baixem o código pronto direto de:
https://github.com/frenetic/django-wars

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *