<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chronosbox &#187; Apps e extensões</title>
	<atom:link href="http://chronosbox.org/blog/categories/django/django-apps-extensions/feed" rel="self" type="application/rss+xml" />
	<link>http://chronosbox.org/blog</link>
	<description>idéias e dicas de uma mente insana trabalhando com TI</description>
	<lastBuildDate>Sun, 30 Oct 2011 04:57:21 +0000</lastBuildDate>
	<language>pt</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>JSONResponse &#8211; Trabalhando com JSON em Django, o jeito fácil.</title>
		<link>http://chronosbox.org/blog/jsonresponse-in-django</link>
		<comments>http://chronosbox.org/blog/jsonresponse-in-django#comments</comments>
		<pubDate>Wed, 14 Apr 2010 03:40:22 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Apps e extensões]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=294</guid>
		<description><![CDATA[Nota: Olá meus caros leitores, apesar do ChronosBox ser um ótimo Blog, eu estou focando meus esforços em um blog conjunto com meu amigo Handrus Nogueira, portanto não deixem de visitar o Dev With Passion! Todos os posts do ChronosBox estarão no Dev With Passion, exceto por alguns comentários novos. Abraços! Existem por ai dezenas [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Nota</strong>: Olá meus caros leitores, apesar do ChronosBox ser um ótimo Blog, eu estou focando meus esforços em um blog conjunto com meu amigo <a href="http://twitter.com/handrus">Handrus Nogueira</a>, portanto não deixem de visitar o <a href="http://devwithpassion.com">Dev With Passion</a>! Todos os posts do ChronosBox estarão no <a href="http://devwithpassion.com">Dev With Passion</a>, exceto por alguns comentários novos. Abraços!</em></p>
<p>Existem por ai dezenas de artigos e snippets sobre como trabalhar com 	<a href="http://www.json.org/">JSON</a><br />
 em <a href="http://www.djangoproject.com/">Django</a>, entretanto vi que a maioria é um pouco vaga e a solução envolve serializar com simplejson e mandar para o HttpResponse. Existem alguns detalhes que normalmente não se cobrem e eu apresento a maneira fácil de trabalhar e um exemplo funcional de JSON em um formulário.<br />
<span id="more-294"></span></p>
<h3> :: Problemas comuns ::</h3>
<p>Os problemas mais comuns que vejo ao trabalhar com JSON em qualquer lugar e não só em Django são:</p>
<ul>
<ol>1. Nem sempre é simples parsear os argumentos enviados</ol>
<ol>2. O simplejson da problemas com alguns tipos de objetos</ol>
<ol>3. Porque não termos um JSONResponse em vez de somente o HttpResponse <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ?</ol>
</ul>
<h3>:: A solução ::</h3>
<ul>
<ol>1. Criar um JSON serializer que manipula objetos que dão problema ao simplejson.dumps</ol>
<ol>2. Criar a JSONResponse, baseada na HttpResponse e no nosso novo serializer</ol>
<ol>3. Achar um meio fácil de parsear os argumentos enviados para obter o JSON
</ul>
<p>A JSONResponse usa o JSON serializer e retorna uma response com os parâmetros enviados pela view. Os parâmetros são os objetos a serem serializados.</p>
<p>Definido isso vamos criar uma APP Django chamada jsonui <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Ela tera 2 models, cidade e estado, 2 views, a main e a que retorna o json, um form simples e os arquivos response.py e utils.py com os métodos que usaremos para gerar o JSON bonitinho.</p>
<h4>:: O JSON serializer ::</h4>
<p>O serializer reside no utils, ele é divido em um JSONEncoder usado pelo simplejson que é responsável por interpretar os objetos que dariam problema, e no serializer propriamente dito que nada mais é um wrapper pro simplejson:</p>
<p class="file">Arquivo: <span class="name">jsonui/utils.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: #808080; font-style: italic;color: #CDC;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> simplejson
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">encoding</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> force_unicode
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">db</span>.<span style="color: black;">models</span>.<span style="color: black;">base</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> ModelBase
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">class</span> LazyJSONEncoder<span style="color: black;color: #CCC;">&#40;</span>simplejson.<span style="color: black;">JSONEncoder</span><span style="color: black;color: #CCC;">&#41;</span>:
    <span style="color: #483d8b;color: #666666;">&quot;&quot;&quot; a JSONEncoder subclass that handle querysets and models objects.
    Add how handle your type of object here to use when when dump json&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> default<span style="color: black;color: #CCC;">&#40;</span><span style="color: #008000;color: #577A61;">self</span>,o<span style="color: black;color: #CCC;">&#41;</span>:
        <span style="color: #808080; font-style: italic;color: #CDC;"># this handles querysets and other iterable types</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">try</span>:
            iterable = <span style="color: #008000;color: #577A61;">iter</span><span style="color: black;color: #CCC;">&#40;</span>o<span style="color: black;color: #CCC;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">except</span> <span style="color: #008000;color: #577A61;">TypeError</span>:
            <span style="color: #ff7700;font-weight:bold;color: #B83A24;">pass</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">else</span>:
            <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> <span style="color: #008000;color: #577A61;">list</span><span style="color: black;color: #CCC;">&#40;</span>iterable<span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;color: #CDC;"># this handlers Models</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">try</span>:
            <span style="color: #008000;color: #577A61;">isinstance</span><span style="color: black;color: #CCC;">&#40;</span>o.__class__,ModelBase<span style="color: black;color: #CCC;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">except</span> <span style="color: #008000;color: #577A61;">Exception</span>:
            <span style="color: #ff7700;font-weight:bold;color: #B83A24;">pass</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">else</span>:
            <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> force_unicode<span style="color: black;color: #CCC;">&#40;</span>o<span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> <span style="color: #008000;color: #577A61;">super</span><span style="color: black;color: #CCC;">&#40;</span>LazyJSONEncoder,<span style="color: #008000;color: #577A61;">self</span><span style="color: black;color: #CCC;">&#41;</span>.<span style="color: black;">default</span><span style="color: black;color: #CCC;">&#40;</span>obj<span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> serialize_to_json<span style="color: black;color: #CCC;">&#40;</span>obj,<span style="color: #66cc66;color: #CCC;">*</span>args,<span style="color: #66cc66;color: #CCC;">**</span>kwargs<span style="color: black;color: #CCC;">&#41;</span>:
    <span style="color: #483d8b;color: #666666;">&quot;&quot;&quot; A wrapper for simplejson.dumps with defaults as:
&nbsp;
    ensure_ascii=False
    cls=LazyJSONEncoder
&nbsp;
    All arguments can be added via kwargs
    &quot;&quot;&quot;</span>
&nbsp;
    kwargs<span style="color: black;color: #CCC;">&#91;</span><span style="color: #483d8b;color: #666666;">'ensure_ascii'</span><span style="color: black;color: #CCC;">&#93;</span> = kwargs.<span style="color: black;">get</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'ensure_ascii'</span>,<span style="color: #008000;color: #577A61;">False</span><span style="color: black;color: #CCC;">&#41;</span>
    kwargs<span style="color: black;color: #CCC;">&#91;</span><span style="color: #483d8b;color: #666666;">'cls'</span><span style="color: black;color: #CCC;">&#93;</span> = kwargs.<span style="color: black;">get</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'cls'</span>,LazyJSONEncoder<span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> simplejson.<span style="color: black;">dumps</span><span style="color: black;color: #CCC;">&#40;</span>obj,<span style="color: #66cc66;color: #CCC;">*</span>args,<span style="color: #66cc66;color: #CCC;">**</span>kwargs<span style="color: black;color: #CCC;">&#41;</span></pre></td></tr></table></div>

<h4>:: A JSONResponse ::</h4>
<p>A JSONResponse reside no response, basicamente ela recebe a lista, dicionário ou qualquer objeto que você envia para o JSONResponse e retorna serializado:</p>
<p class="file">Arquivo: <span class="name">jsonui/response.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: #808080; font-style: italic;color: #CDC;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> utils <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> serialize_to_json
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> HttpResponseForbidden, HttpResponse
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">class</span> JSONResponse<span style="color: black;color: #CCC;">&#40;</span>HttpResponse<span style="color: black;color: #CCC;">&#41;</span>:
    <span style="color: #483d8b;color: #666666;">&quot;&quot;&quot; JSON response class &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> <span style="color: #0000cd;color: #343832;">__init__</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #008000;color: #577A61;">self</span>,content=<span style="color: #483d8b;color: #666666;">''</span>,json_opts=<span style="color: black;color: #CCC;">&#123;</span><span style="color: black;color: #CCC;">&#125;</span>,mimetype=<span style="color: #483d8b;color: #666666;">&quot;application/json&quot;</span>,<span style="color: #66cc66;color: #CCC;">*</span>args,<span style="color: #66cc66;color: #CCC;">**</span>kwargs<span style="color: black;color: #CCC;">&#41;</span>:
        <span style="color: #483d8b;color: #666666;">&quot;&quot;&quot;
        This returns a object that we send as json content using 
        utils.serialize_to_json, that is a wrapper to simplejson.dumps
        method using a custom class to handle models and querysets. Put your
        options to serialize_to_json in json_opts, other options are used by
        response.
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">if</span> content:
            content = serialize_to_json<span style="color: black;color: #CCC;">&#40;</span>content,<span style="color: #66cc66;color: #CCC;">**</span>json_opts<span style="color: black;color: #CCC;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">else</span>:
            content = serialize_to_json<span style="color: black;color: #CCC;">&#40;</span><span style="color: black;color: #CCC;">&#91;</span><span style="color: black;color: #CCC;">&#93;</span>,<span style="color: #66cc66;color: #CCC;">**</span>json_opts<span style="color: black;color: #CCC;">&#41;</span>
        <span style="color: #008000;color: #577A61;">super</span><span style="color: black;color: #CCC;">&#40;</span>JSONResponse,<span style="color: #008000;color: #577A61;">self</span><span style="color: black;color: #CCC;">&#41;</span>.<span style="color: #0000cd;color: #343832;">__init__</span><span style="color: black;color: #CCC;">&#40;</span>content,mimetype,<span style="color: #66cc66;color: #CCC;">*</span>args,<span style="color: #66cc66;color: #CCC;">**</span>kwargs<span style="color: black;color: #CCC;">&#41;</span></pre></td></tr></table></div>

<h4>:: Botando pra funcionar na view. ::</h4>
<p>Sem mais rodeios, vamos ver como funciona. Nós temos duas views:</p>
<ul>
<li><em>mainview</em>: chama o form e renderiza um template com o código javascript necessário para executar o POST e renderizar o JSON que obtemos como resposta.</li>
<li><em>json_get_city</em>: responsável por retornar as cidades de acordo com o estado enviado.</li>
</ul>
<p></p>
<p class="file">Arquivo: <span class="name">urls.py</span> <span class="line">@ 17</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>17
18
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: black;color: #CCC;">&#40;</span>r<span style="color: #483d8b;color: #666666;">'^$'</span>,<span style="color: #483d8b;color: #666666;">'jsonui.views.mainview'</span><span style="color: black;color: #CCC;">&#41;</span>,
<span style="color: black;color: #CCC;">&#40;</span>r<span style="color: #483d8b;color: #666666;">'^ajax/city/'</span>,<span style="color: #483d8b;color: #666666;">'jsonui.views.json_get_city'</span><span style="color: black;color: #CCC;">&#41;</span>,</pre></td></tr></table></div>

<p class="file">Arquivo: <span class="name">jsonui/views.py</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: #808080; font-style: italic;color: #CDC;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> render_to_response
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> RequestContext
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> models <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> City,State
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> forms <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> CityForm
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> utils <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> qdct_as_kwargs
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> response <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> JSONResponse
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> mainview<span style="color: black;color: #CCC;">&#40;</span>request<span style="color: black;color: #CCC;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> render_to_response<span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'base.html'</span>,<span style="color: black;color: #CCC;">&#123;</span><span style="color: #483d8b;color: #666666;">'form'</span>: CityForm<span style="color: black;color: #CCC;">&#40;</span><span style="color: black;color: #CCC;">&#41;</span> <span style="color: black;color: #CCC;">&#125;</span>,
        context_instance=RequestContext<span style="color: black;color: #CCC;">&#40;</span>request<span style="color: black;color: #CCC;">&#41;</span><span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> json_get_city<span style="color: black;color: #CCC;">&#40;</span>request<span style="color: black;color: #CCC;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">if</span> <span style="color: #ff7700;font-weight:bold;color: #B83A24;">not</span> request.<span style="color: black;">method</span> == <span style="color: #483d8b;color: #666666;">&quot;POST&quot;</span>:
        <span style="color: #808080; font-style: italic;color: #CDC;"># return all cities if any filter was send</span>
        <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> JSONResponse<span style="color: black;color: #CCC;">&#40;</span>City.<span style="color: black;">objects</span>.<span style="color: black;">order_by</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'name'</span><span style="color: black;color: #CCC;">&#41;</span><span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;color: #CDC;"># get cities with request.POST as filter arguments</span>
    cities = City.<span style="color: black;">objects</span>.<span style="color: #008000;color: #577A61;">filter</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #66cc66;color: #CCC;">**</span>qdct_as_kwargs<span style="color: black;color: #CCC;">&#40;</span>request.<span style="color: black;">POST</span><span style="color: black;color: #CCC;">&#41;</span><span style="color: black;color: #CCC;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'name'</span><span style="color: black;color: #CCC;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;color: #CDC;">#return JSONResponse with id and name</span>
    <span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> JSONResponse<span style="color: black;color: #CCC;">&#40;</span>cities.<span style="color: black;">values</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: #483d8b;color: #666666;">'id'</span>,<span style="color: #483d8b;color: #666666;">'name'</span><span style="color: black;color: #CCC;">&#41;</span><span style="color: black;color: #CCC;">&#41;</span></pre></td></tr></table></div>

<p>O método <em>qdct_as_kwargs</em> é responsável por retornar um dicionário que é passado parao método filter de um objeto a partir do request.POST ou request.GET. É uma magica legal que agiliza e muito a criação de views como essa.</p>
<p>Assim que a url /ajax/city/ recebe o POST ela obtem as cidades usando o <em>qdct_as_kwargs</em> e retorna a <em>JSONResponse</em>, no javascript a resposta é um JSON pronto para usar.</p>
<p class="file">Arquivo: <span class="name">jsonui/utils.py</span> <span class="line">@ 44</span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>44
45
46
47
48
</pre></td><td class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> qdct_as_kwargs<span style="color: black;color: #CCC;">&#40;</span>qdct<span style="color: black;color: #CCC;">&#41;</span>:
kwargs=<span style="color: black;color: #CCC;">&#123;</span><span style="color: black;color: #CCC;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">for</span> k,v <span style="color: #ff7700;font-weight:bold;color: #B83A24;">in</span> qdct.<span style="color: black;">items</span><span style="color: black;color: #CCC;">&#40;</span><span style="color: black;color: #CCC;">&#41;</span>:
    kwargs<span style="color: black;color: #CCC;">&#91;</span><span style="color: #008000;color: #577A61;">str</span><span style="color: black;color: #CCC;">&#40;</span>k<span style="color: black;color: #CCC;">&#41;</span><span style="color: black;color: #CCC;">&#93;</span>=v
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">return</span> kwargs</pre></td></tr></table></div>

<p>O javascript responsável por mandar o POST esta no template <em>base.html</em> que é renderizado pela <em>mainview</em>. Este é o trecho relevante:</p>
<p class="file">Arquivo: <span class="name">templates/base.html</span> <span class="line">@ 10</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;color: #FCFFBA;">$<span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #003366; font-weight: bold;color: #577A61;">function</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #009900;color: #CCC;">&#41;</span><span style="color: #009900;color: #CCC;">&#123;</span>
    $<span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #3366CC;color: #666666;">&quot;#id_state&quot;</span><span style="color: #009900;color: #CCC;">&#41;</span>.<span style="color: #660066;">change</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #003366; font-weight: bold;color: #577A61;">function</span><span style="color: #009900;color: #CCC;">&#40;</span>e<span style="color: #009900;color: #CCC;">&#41;</span><span style="color: #009900;color: #CCC;">&#123;</span>
        $.<span style="color: #660066;">post</span><span style="color: #009900;color: #CCC;">&#40;</span>
            <span style="color: #006600; font-style: italic;color: #CDC;">// url to post</span>
            <span style="color: #3366CC;color: #666666;">&quot;/ajax/city/&quot;</span><span style="color: #339933;color: #CCC;">,</span>
            <span style="color: #006600; font-style: italic;color: #CDC;">// args</span>
            <span style="color: #009900;color: #CCC;">&#123;</span>state__id<span style="color: #339933;color: #CCC;">:</span>$<span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #000066; font-weight: bold;color: #B83A24;">this</span><span style="color: #009900;color: #CCC;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #009900;color: #CCC;">&#41;</span><span style="color: #009900;color: #CCC;">&#125;</span><span style="color: #339933;color: #CCC;">,</span>
            <span style="color: #006600; font-style: italic;color: #CDC;">// response callback</span>
            <span style="color: #003366; font-weight: bold;color: #577A61;">function</span><span style="color: #009900;color: #CCC;">&#40;</span>data<span style="color: #339933;color: #CCC;">,</span>text<span style="color: #339933;color: #CCC;">,</span>xhrobject<span style="color: #009900;color: #CCC;">&#41;</span><span style="color: #009900;color: #CCC;">&#123;</span>
                <span style="color: #006600; font-style: italic;color: #CDC;">// uncomment if you wanna to see objects on firebug console</span>
                <span style="color: #006600; font-style: italic;color: #CDC;">//console.log(data,text,xhrobject)</span>
                $<span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #3366CC;color: #666666;">&quot;#id_city&quot;</span><span style="color: #009900;color: #CCC;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #009900;color: #CCC;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #009900;color: #CCC;">&#41;</span>
                    .<span style="color: #660066;">append</span><span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #3366CC;color: #666666;">&quot;&lt;option selected=<span style="color: #000099; font-weight: bold;">\&quot;</span>selected<span style="color: #000099; font-weight: bold;">\&quot;</span> value=<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;------&lt;/option&gt;&quot;</span><span style="color: #009900;color: #CCC;">&#41;</span>
                <span style="color: #000066; font-weight: bold;color: #B83A24;">for</span> <span style="color: #009900;color: #CCC;">&#40;</span>i <span style="color: #000066; font-weight: bold;color: #B83A24;">in</span> data<span style="color: #009900;color: #CCC;">&#41;</span> <span style="color: #009900;color: #CCC;">&#123;</span>
                    i <span style="color: #339933;color: #CCC;">=</span> data<span style="color: #009900;color: #CCC;">&#91;</span>i<span style="color: #009900;color: #CCC;">&#93;</span>
                    $<span style="color: #009900;color: #CCC;">&#40;</span><span style="color: #3366CC;color: #666666;">&quot;#id_city&quot;</span><span style="color: #009900;color: #CCC;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;color: #CCC;">&#40;</span>
                        <span style="color: #3366CC;color: #666666;">&quot;&lt;option value=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #339933;color: #CCC;">+</span>i.<span style="color: #660066;">id</span><span style="color: #339933;color: #CCC;">+</span><span style="color: #3366CC;color: #666666;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span><span style="color: #339933;color: #CCC;">+</span>i.<span style="color: #000066;color: #8FB394;">name</span><span style="color: #339933;color: #CCC;">+</span><span style="color: #3366CC;color: #666666;">&quot;&lt;/option&gt;&quot;</span>
                    <span style="color: #009900;color: #CCC;">&#41;</span>
                <span style="color: #009900;color: #CCC;">&#125;</span>
            <span style="color: #009900;color: #CCC;">&#125;</span><span style="color: #009900;color: #CCC;">&#41;</span>
    <span style="color: #009900;color: #CCC;">&#125;</span><span style="color: #009900;color: #CCC;">&#41;</span>
<span style="color: #009900;color: #CCC;">&#125;</span><span style="color: #009900;color: #CCC;">&#41;</span></pre></td></tr></table></div>

<p>Este código executa um POST para /ajax/city/ e na volta preenche o select de cidades com o objeto retornado.</p>
<h3>:: Finalizando ::</h3>
<p>Reproduzindo javascripts similares e usando o qdct_as_kwargs e o JSONResponse como usado na view <em>json_get_city</em> você pode facílmente criar várias views ou até uma view mais genérica que pegue de qualquer modelo. Basta deixar a imaginação fluir <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Você pode baixar o projeto completo aqui: <a href="http://files.chronosbox.org/jsonproject.tbz2">jsonproject.tbz2</a> (<a href="http://files.chronosbox.org/jsonproject.tbz2.md5">MD5 Hash</a>) (<a href="http://chronosbox.org/jsonproject.tbz2">mirror</a>, <a href="http://chronosbox.org/jsonproject.tbz2.md5">mirror MD5</a>)</p>
<p>Eu construi ele usando Django 1.2, mas roda em qualquer versão acima da 1.0.</p>
<p>Divirta-se, contribua, comente <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Abraços!</p>
<p>** UPDATES</p>
<ul>
<li>Se você está ganhando erros 403, cheque permissões na view ajax e o CSRF (<a href="#comment-465">dica por Nick Young</a>)</li>
<li>Se você precisa de dados adicionais na resposta JSON <a href="#comment-409">veja a ajuda que dei ao Jim</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/jsonresponse-in-django/feed</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Manipulando erros Http 403 (permissão negada) no Django</title>
		<link>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django</link>
		<comments>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django#comments</comments>
		<pubDate>Tue, 24 Nov 2009 20:35:59 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Apps e extensões]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[403]]></category>
		<category><![CDATA[denied]]></category>
		<category><![CDATA[forbidden]]></category>
		<category><![CDATA[Http403]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[negado]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=240</guid>
		<description><![CDATA[Neste post, apresento um novo Middleware, concebido para tratar erros 403 (Http Forbidden, permissão negada) como trabalhamos com os erros 404 no Django.]]></description>
			<content:encoded><![CDATA[<p><em><strong>Nota</strong>: Olá meus caros leitores, apesar do ChronosBox ser um ótimo Blog, eu estou focando meus esforços em um blog conjunto com meu amigo <a href="http://twitter.com/handrus">Handrus Nogueira</a>, portanto não deixem de visitar o <a href="http://devwithpassion.com">Dev With Passion</a>! Todos os posts do ChronosBox estarão no <a href="http://devwithpassion.com">Dev With Passion</a>, exceto por alguns comentários novos. Abraços!</em></p>
<p>Olá pessoal <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Recentemente, precisei usar o módulo <a href="http://docs.djangoproject.com/en/dev/topics/auth/#permissions">Auth do Django e suas permissões</a>. É bastante interessante como você pode definir permissões por módulo e usar nas views, templates, etc.</p>
<p>Nosso código de hoje vem da necessidade de trabalhar facilmente com <a href="http://en.wikipedia.org/wiki/HTTP_403">permissões negadas</a>, onde o Django fornece apenas um <a href="http://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses">HttpResponseForbidden</a>, o que não é exatamente interessante de manipular, pois o ideal seria algo como a manipulação de erros 404.</p>
<p>Com essa necessidade desenvolvi um <a href="http://docs.djangoproject.com/en/dev/topics/http/middleware/">Middleware</a> que intercepta exceções <a href="http://en.wikipedia.org/wiki/HTTP_403">Http403</a> (vem junto com o pacote), e retorna uma das seguintes opções, na ordem de prioridade:</p>
<ol>
<li>Uma view customizada, configurada usando handler403 no seu urls.py</li>
<li>Renderiza o template 403.html</li>
<li>Renderiza um template Hardcoded</li>
</ol>
<p>Para usar o Middleware, siga os procedimentos:</p>
<ol>
<li>Baixe o projeto no fim deste post, vamos usa-lo de exemplo, ele se chama http403project.</li>
<li>Descompacte e copie o arquivo http.py para algum lugar do seu projeto, no http403project ele fica na raiz.</li>
<li>Adicione o middleware ao settings.py:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;">MIDDLEWARE_CLASSES = <span style="color: black;color: #CCC;">&#40;</span>
      <span style="color: #808080; font-style: italic;color: #CDC;"># ...</span>
      <span style="color: #483d8b;color: #666666;">'http403project.http.Http403Middleware'</span>,
<span style="color: black;color: #CCC;">&#41;</span></pre></div></div>

</li>
<li>De raise na view, ex:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;color: #FCFFBA;"><span style="color: #ff7700;font-weight:bold;color: #B83A24;">from</span> http <span style="color: #ff7700;font-weight:bold;color: #B83A24;">import</span> Http403
<span style="color: #ff7700;font-weight:bold;color: #B83A24;">def</span> Http403View<span style="color: black;color: #CCC;">&#40;</span>request<span style="color: black;color: #CCC;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;color: #B83A24;">raise</span> Http403<span style="color: black;color: #CCC;">&#40;</span>u<span style="color: #483d8b;color: #666666;">&quot;This is custom message for permission denied.&quot;</span><span style="color: black;color: #CCC;">&#41;</span></pre></div></div>

</li>
<li>Configure sua view customizada ou template se desejar. Seu template deve ter o nome de 403.html, sua view recebe os argumentos request e exception, o argumento exception contem a mensagem enviada pelo usuário <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . No projeto exemplo ele está renderizando o template 403.html, mas existe uma view de exemplo bastante simples no arquivo urls.py
</li>
</ol>
<p><strong>Projeto:</strong> <a href="http://chronosbox.org/blog/django-projects/http403project.tgz">http403project.tgz</a></p>
<p>Ok, é isto, super simples, por hoje é só <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , divirtam-se!</p>
]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/manipulando-erros-http-403-permissao-negada-no-django/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django apps (coleção) &#8211; parte 1</title>
		<link>http://chronosbox.org/blog/django-apps-collection-part-1</link>
		<comments>http://chronosbox.org/blog/django-apps-collection-part-1#comments</comments>
		<pubDate>Sun, 19 Jul 2009 06:14:25 +0000</pubDate>
		<dc:creator>Felipe 'chronos' Prenholato</dc:creator>
				<category><![CDATA[Apps e extensões]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[compress]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[graphs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[plot]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ratings]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sphinx]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tagging]]></category>
		<category><![CDATA[tags]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[utils]]></category>

		<guid isPermaLink="false">http://chronosbox.org/blog/?p=196</guid>
		<description><![CDATA[Eu estou trabalhando atualmente com Python e Django, a linguagem e o framework são excelentes e como pretendo desenvolver um projeto bastante interessante com ele estou listando aqui alguns dos apps que achei bastante interessante em uma rápida pesquisa no Django Plugables e outros lugares. Estou dividindo o artigo em duas partes e postarei uma [...]]]></description>
			<content:encoded><![CDATA[<p>Eu estou trabalhando atualmente com <a href="http://www.python.org/" target="_blank">Python</a> e <a href="http://www.djangoproject.com/" target="_blank">Django</a>, a linguagem e o framework<br />
são excelentes e como pretendo desenvolver um projeto bastante interessante<br />
com ele estou listando aqui alguns dos apps que achei bastante interessante<br />
em uma rápida pesquisa no <a href="http://djangoplugables.com/" target="_blank">Django Plugables</a> e outros lugares.</p>
<p>Estou dividindo o artigo em duas partes e postarei uma por semana, coloquem<br />
suas sugestões nos comentaŕios <img src='http://chronosbox.org/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p><span id="more-196"></span><strong>django-openid</strong>:</p>
<ul>
<li><strong> descrição:</strong> suporte a rede <a href="http://openid.net/" target="_blank">OpenID</a></li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-openid/" target="_blank">http://code.google.com/p/django-openid/</a></li>
<li><strong>opinião:</strong> só se você for usar <a href="http://openid.net/" target="_blank">OpenID</a> para algo&#8230;eu particularmente não dou muito para a OpenID por hora mas acredito que tenha futuro.</li>
</ul>
<h4><strong>django-ratings</strong>:</h4>
<ul>
<li> <strong>descrição:</strong> sistema básico de ratings, eu não usei</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-ratings/">http://code.google.com/p/django-ratings/</a></li>
<li><strong>opinião:</strong> eu não usei, mas o app é bem simples, tem um campo para modelo, manager e models, eu esperava talvez algo como tags, etc. Recentemente eu desenvolvi um sistema customizado de ratings, fechado e bastante especifico. Em breve precisarei de um mais genérico e então farei algo em cima deste app.</li>
</ul>
<h4><strong>django-sphinx</strong></h4>
<ul>
<li><strong>descrição:</strong> permite busca fulltext usando o mecanismo <a href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a>, que é melhor que o default do MySQL.</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-sphinx/" target="_blank">http://code.google.com/p/django-sphinx/</a></li>
<li><strong>opinião:</strong> muito, muito útil, infelizmente ele precisa do sphinx instalado, o que não ajuda muito pois vários hosts não tem este suporte, entretanto o sphinx é bem mais interessante que outros mecanismos de busca alternativos já que é escrito em C (ou C++) e não em java. Com certeza vou usar em breve.</li>
</ul>
<h4><strong>django-tagging</strong></h4>
<ul>
<li> <strong>descrição:</strong> sistema genérico mas eficiente para trabalhar com tags</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-tagging/" target="_blank">http://code.google.com/p/django-tagging/</a></li>
<li><strong>opção:</strong> Muito útil, este com certeza usarei em todos os meus projetos e provavelmente serei um dos contribuidores, pretendo integrar ele a algum sistema de ratings e busca.</li>
</ul>
<h4><strong>django-template-utils</strong></h4>
<ul>
<li><strong> descrição:</strong> Várias adições muito muito boas para o podre sistema de templates do django</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-template-utils/" target="_blank">http://code.google.com/p/django-template-utils/</a></li>
<li><strong>opinião:</strong> Necessário. É conhecido que o Django tem um sistema de templates (intencionalmente:) limitado, para questões de segurança e da separação da lógica na parte das views, forms e models. O problema é que eles limitaram demais, e este pacote traz alguma vida adicional a ele. Eu já estou usando.</li>
</ul>
<h4><strong>django-compress</strong></h4>
<ul>
<li><strong> descrição:</strong> compacta seu js e css</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-compress/" target="_blank">http://code.google.com/p/django-compress/</a></li>
<li><strong>opinião:</strong> faz parte das otimizações de qualquer site otimizar css e js, e ao unificar em um só arquivo melhora no número de requests. o app é realmente muito útil e eu pretendo usá-lo daqui para frente.</li>
</ul>
<h4>django-graphs</h4>
<ul>
<li><strong> descrição:</strong> pelo que li, gráficos bonitinhos para o Django</li>
<li><strong>site:</strong> <a href="http://code.google.com/p/django-graphs/" target="_blank">http://code.google.com/p/django-graphs/</a></li>
<li><strong>opção:</strong> oferece métodos para gerar gráficos usando cairo e PIL, é bastante interessante mas &#8230; eu particulamente estou interessado em algo que gere gráficos onde eu possa interagir, preferencialmente não em flash, já que o suporte a 64 bits ainda é fraco no linux.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://chronosbox.org/blog/django-apps-collection-part-1/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

