O
django não tem um comando que gere automagicamente um
CRUD para você. Porém com poucas linhas de código e
generic views é possivel fazer isso rapidamente. No exemplo que segue eu vou utilizar o meu módulo de localidade que corresponde aos models Cidade e Estado. O código é simples e depois é só adaptar à sua necessidade. Então vamos por partes:
No urls.py do projeto eu verifico o modulo selecionado e dou um include do urls.py da app:
from django.conf.urls.defaults import *
from django.conf import settings
urlpatterns = patterns('',
(r'^localidade/', include('localidade.urls')),
)
No urls.py da app foram criadas 4 regras para listagem, inserção, edição e exclusão e registros. O model que será trabalhado é passado via parâmetro e para edição e exclusão é informada a chave (id):
from django.conf.urls.defaults import patterns
urlpatterns = patterns('localidade.views',
(r'^lista/(?P<model>\w+)/$', 'lista'),
(r'^adiciona/(?P<model>\w+)/$', 'adiciona_ou_atualiza'),
(r'^atualiza/(?P<model>\w+)/(?P<key>\d+)/$', 'adiciona_ou_atualiza'),
(r'^remove/(?P<model>\w+)/(?P<key>\d+)/$', 'remove'),
)
O views.py implementa os 4 métodos utilizando generic views:
from django.http import Http404
from django.views.generic.list_detail import object_list
from django.views.generic.create_update \
import create_object, update_object, delete_object
from django.db.models import get_model
def lista(request, model):
model_object = get_model('localidade', model)
if model_object:
model_list = model_object.objects.all()
else:
raise Http404()
return object_list(request, queryset=model_list)
def adiciona_ou_atualiza(request, model, key=None):
model_object = get_model('localidade', model)
if model_object:
if key:
return update_object(
request,
model=model_object,
object_id=key,
post_save_redirect='/localidade/lista/%s/' % model,
)
else:
return create_object(
request,
model=model_object,
post_save_redirect='/localidade/adiciona/%s/' % model,
)
else:
raise Http404()
def remove(request, model, key):
model_object = get_model('localidade', model)
if model_object:
return delete_object(
request,
model=model_object,
object_id=key,
post_delete_redirect='/localidade/lista/%s/' % model,
template_name='object_confirm_delete.html',
)
else:
raise Http404()
Algumas observações no caso das views. O get_model procura pelo model passado na url baseado na app que você informa (é uma mão na roda esse método). O
object_list procura um template com o nome model_list.html (cidade_list.html ou estado_list.html) e disponibiliza um object_list para você percorrer e exibir os valores. O
create_object e o
update_object procuram por um model_form.html (cidade_form.html ou estado_form.html) e disponibiliza uma variável form para que você possa exibir o formulário sem trabalho. Todos os métodos fazem a busca do template na pasta de templates da app. Os templates ficam assim:
_list.html
<html>
{% if object_list %}
<table>
<thead>
<tr>
<th>Id</th>
<th>Nome</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>{{ object.id }}</td>
<td>{{ object.nome }}</td>
<td>
<a href="{% url localidade.views.remove "object" object.id %}">
Excluir
</a>
</td>
<td>
<a href="{% url localidade.views.adiciona_ou_atualiza "object" object.id %}">
Alterar
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>Sem registros para listar</p>
{% endif %}
</html>
_form.html:
<html>
<form action="" method="POST">
{{ form.as_p }}
<input type="submit" value="Gravar" />
</form>
</html>
O
delete_object, quando via GET, procura por um model_confirm_delete.html. Como em todos os casos eu tenho efetuado a exclusão via GET e ficaria repetitivo ter em cada pasta de template de cada aplicação um template idêntico, criei apenas um na pasta de templates do projeto com o nome object_confirm_delete.html com o seguinte conteúdo:
<html>
<form method='post' action=''>
<p>Confirma a exclusão do registro ? </p>
<input type="submit" />
</form>
</html>
E esta feito. Você tem o seu CRUD pronto. Com base nisso, é possível criar generic views e fazer com que seu crud fique ainda mais compacto sem perder funcionalidade, legibilidade e facilidade na manutenção.