Implementando Ajax usando JSON
Ajax é uma tecnologia que utiliza Javascript para enviar e receber dados à um servidor sem precisar atualizar a página em exibição no navegador, e JSON é um formato para troca de dados, onde os dados enviados são semelhantes à uma tupla, contendo uma chave e um valor. Pode-se utilizar ajax com outros formatos para troca de dados, mas vamos ficar com o JSON por ser mais simples de se trabalhar.
Primeiro vamos escrever nossa função javascript responsável por requisitar ao servidor as ruas cadastradas a partir do id do bairro fornecido, dentro do arquivo sigep.js. É uma função genérica que pode ser utilizada com outros elementos e outras tabelas. Lembrando que é extremamente necessário carregar a biblioteca JQuery no código do template antes de usar a função abaixo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** * @param string url - URL que processara a requisicao do cliente * @param string objHtmlReturn - ID do objeto HTML onde sera exibido o resultado * @param int id - Valor enviado como base para obter um retorno */ function comboAjax(url,objHtmlReturn,id) { // Cria uma variável dados em formato JSON, com 1 chave e 1 valor dados = {'id':id}; // É inserido um elemento option dentro do elemento select $("#"+objHtmlReturn).html('<option value="0">Carregando...</option>'); $.ajax({ type: "POST", url: url, dataType: "json", data: dados, success: function(retorno){ $("#"+objHtmlReturn).empty(); $.each(retorno, function(i, item){ $("#"+objHtmlReturn).append('<option value="'+item.pk+'">'+item.fields[fieldreturn]+'</option>'); }); }, error: function(erro) { alert('Erro. Sem retorno da requisicao.'); } }); } |
Modificaremos o elemento select dentro do template clienteform.html de modo a usar a função acima. Atualmente está declarado assim:
1 2 3 4 5 | <select name="bairro" id="id_bairro">
{% for b in bairros %}
<option value="{{b.id}}">{{b.bairro}}</option>
{% endfor %}
</select> |
Alterando para incluir o evento onchange():
1 2 3 4 5 | <select name="bairro" id="id_bairro" onchange="comboAjax('/cliente/getlogradouros/','id_logradouro',this.value);">
{% for b in bairros %}
<option value="{{b.id}}">{{b.bairro}}</option>
{% endfor %}
</select> |
Quando for selecionado um bairro, será disparado o evento onchange(), chamando a função comboAjax(), que enviará uma requisição à view /cliente/getlogradouros, que por sua vez fará uma consulta ao banco de dados retornando todos os logradouros a partir do id do bairro fornecido e exibindo o resultado no elemento select com id='id_logradouro'.
Vamos escrever a view responsável por tratar nossa requisição ajax. No arquivo views.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django.core import serializers from django.utils import simplejson def getlogradouros(request): if request.method == 'POST': id = request.POST.get('id'); lista = Logradouro.objects.filter(bairro=id) if lista.count() > 0: json = serializers.serialize("json",lista) else: lista = [{"pk":"0","fields":{'logradouro':"Nenhum registro"}}] json = simplejson.dumps(lista) return HttpResponse(json,mimetype="application/json") getlogradouros = login_required(getlogradouros) |
E para finalizar, vamos mapear a URL alterando o urlpatterns no arquivo urls.py:
1 | (r'^cliente/getlogradouros/$','sigep.cliente.views.getlogradouros'), |
Conclusão
Esse artigo não visa discutir assuntos relacionados à engenharia de software, modelagem de dados e orientação à objetos. Nada disso foi analisado no processo de desenvolvimento visto que foge do objetivo de ser apenas uma apresentação rápida sobre o framework. Django possui recursos fantásticos e tem tudo para estar entre os grandes.
Desenvolvemos uma aplicação simples para cadastro de clientes, com uma interface horrível e um bug ao tentar editar os dados do cliente. A questão da interface pode ser resolvida com uso de css e javascript, e quanto ao bug vou deixar como exercício para vocês tentarem resolver. O bug aparece quando tentamos editar o cliente – não mostra o endereço. O correto seria exibir todos os bairros e logradouros cadastrados e aparecer selecionados àqueles que compõem o endereço do cliente.
Em breve estarei disponibilizando mais artigos de modo a completar o sistema.
Dúvidas e sugestões serão bem-vindas.














Posted in
Tags: 
Muito legal o tuto, parabéns!!
Hugs!!
Muito bom, dei só uma olhada mas com esse tipo de material o Django ira crescer cada vez mais.
Fala rapaz parabens ai ficou muito bom ,,
uma abraço
Gustavo,
Meus sinceros parabéns pelo material, está excelente.
Um desafio:
– O que tu achas de fazer uma versão desse ajax com a biblioteca mootools ?
Parabéns Gustavo,
Ouvi falar da eficiência do Django a poucos dias e procurei algo simples que pudesse me comprovar isso…
Vc sintetizou nesse post tudo o que eu estava procurando! Agora é só me aprofundar no framework. Se existirem mais posts como esse por aí tenho certeza que a comunidade Python e Django vão crescer muito em quantidade e principalmente em qualidade! 100% produção…
Verifiquei que no arquivo forms.py ao usarmos o método mark_safe, devemos incluir a classe safestring do Django.
Para resolver o problema devemos incluir a linha from django.utils.safestring import mark_safe no início do arquivo /cliente/forms.py para importar o método mark_safe.
Abs…
na linha
$(“#”+objHtmlReturn).append(”+item.fields[fieldreturn]+”);
qd escolho o bairro da um erro dizendo q a palavra ou o campo “fieldreturn” nao está definido por isso nao carrega as ruas no outro select
Excelente tutorial, colega.
Parabéns XD
Opa, tudo bom.
Primeiro quero parabenizá-lo pelo artigo. Segundo informo que o método javascript declarado acima para atualizar o select html está quebrado. Criei outro método jQuery, que ficou assim:
$( function() {
$(“select#id_bairro”).change(
function() {
$.getJSON( “/cliente/getlogradouros?id=” + $(this).val(),
function(j) {
var options = ‘———- ‘;
for ( var i = 0; i < j.length; i++) {
options += ”
+ j[i].fields['logradouro']
+ ”;
}
$(“#id_logradouro”).html(options);
$(“#id_logradouro option:first”).attr(’selected’,
’selected’);
$(“#id_logradouro”).attr(‘disabled’, false);
})
$(“#id_logradouro”).attr(’selected’, ’selected’);
})
})
Para que ele funcione, o metodo no módulo views.py precisa ser mudado para o método GET, que no meu caso ficou assim:
def getlogradouros( request ):
id = int( request.GET.get( ‘id’ ) )
lista = Logradouro.objects.filter( bairro = id )
if lista.count() > 0:
json = serializers.serialize( “json”, lista )
else:
lista = [{"pk":"0", "fields":{'logradouro':"Nenhum registro"}}]
json = simplejson.dumps( lista )
return HttpResponse( json, mimetype = “application/json” )
Ola gostei do material que vc publicou, vc terminou a segunda parte deste tutorial referente ao sistema???
@Luiz, nao cheguei a terminar, mas escrevi um artigo aqui no blog que fala um pouco sobre. O titulo é “Servidor Linux com Proxy e Controle de Banda”.
[]’s