<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Douglas Miranda</title><link>http://douglasmiranda.com/</link><description>Python, Django, Desenvolvimento de Software e a arte ninja. YAH!</description><language>pt-BR</language><lastBuildDate>Thu, 31 May 2012 01:48:59 -0000</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/douglasmiranda" /><feedburner:info uri="douglasmiranda" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Json View - Django class-based generic views - III</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/IV5d3-t6rec/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;# Se quer saber primeiro sobre class based generic views e esta s&amp;eacute;rie de artigos que estou fazendo, basta ler &lt;a href="/artigo/listview-django-class-based-generic-views-i/#class-based-generic-views" target="_blank"&gt;este trecho do primeiro artigo da s&amp;eacute;rie&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Vamos imaginar que voc&amp;ecirc; precisa serializar a &lt;em&gt;Response&lt;/em&gt; de uma view tua para utilizar os dados e trabalh&amp;aacute;-los com&lt;em&gt; Ajax&lt;/em&gt;, e/ou para criar uma API, ou seja l&amp;aacute; qual for o motivo, se voc&amp;ecirc; usa as &lt;strong&gt;class based generic views&lt;/strong&gt; do Django fica mais f&amp;aacute;cil e elegante. Neste artigo veremos um exemplo simples de como faz&amp;ecirc;-lo.&lt;/p&gt;
&lt;p&gt;Refor&amp;ccedil;ando novamente que tomo por base o c&amp;oacute;digo do &lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/" target="_blank"&gt;reposit&amp;oacute;rio&lt;/a&gt; que criei no github para os exemplos.&lt;/p&gt;
&lt;h2&gt;&lt;a name="Estendendo-uma-ListView-para-criarmos-nossa-JsonView"&gt;&lt;/a&gt;&lt;a href="#Estendendo-uma-ListView-para-criarmos-nossa-JsonView"&gt;Estendendo uma &lt;em&gt;ListView&lt;/em&gt; para criarmos nossa &lt;em&gt;JsonView&lt;/em&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;O arquivo &lt;em&gt;&lt;strong&gt;views.py&lt;/strong&gt;&lt;/em&gt;, ou em nosso caso &lt;em&gt;&lt;strong&gt;list_and_detail.py&lt;/strong&gt;&lt;/em&gt;, tem uma view&lt;em&gt;&lt;/em&gt; que lista os objetos de uma "lista de reprodu&amp;ccedil;&amp;atilde;o", como abaixo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="kwd"&gt;from&lt;/span&gt;&lt;span class="pln"&gt; django&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;views&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;generic &lt;/span&gt;&lt;span class="kwd"&gt;import&lt;/span&gt;&lt;span class="typ"&gt;ListView&lt;/span&gt;&lt;br /&gt;&lt;span class="kwd"&gt;from&lt;/span&gt;&lt;span class="pln"&gt; app_exemplo&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;models &lt;/span&gt;&lt;span class="kwd"&gt;import&lt;/span&gt;&lt;span class="typ"&gt;ListaDeReproducao&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="typ"&gt; ListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;ListView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; model &lt;/span&gt;&lt;span class="pun"&gt;= &lt;/span&gt;&lt;span class="typ"&gt;ListaDeReproducao&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Com o exemplo acima teremos uma lista de objetos de &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListaDeReproducao&lt;/code&gt; , por&amp;eacute;m o retorno ser&amp;aacute; em &lt;em&gt;text/html&lt;/em&gt; do modo convencional, em que precisamos renderizar um template e tudo mais.&lt;/p&gt;
&lt;p&gt;Para aproveitarmos poss&amp;iacute;veis comportamentos, personaliza&amp;ccedil;&amp;otilde;es e/ou mesmo as defini&amp;ccedil;&amp;otilde;es dos atributos j&amp;aacute; contidos em &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListaDeReproducao&lt;/code&gt; vamos estender esta &lt;em&gt;view&lt;/em&gt; e fazer a modifica&amp;ccedil;&amp;atilde;o no m&amp;eacute;todo &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get(self, request, *args, **kwargs)&lt;/code&gt; para termos um &lt;em&gt;response&lt;/em&gt; &lt;em&gt;application/json&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Em &lt;strong&gt;&lt;em&gt;views.json&lt;/em&gt;&lt;/strong&gt; (json.py) eu tenho isto:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# coding: utf-8&lt;br /&gt;from django.http import HttpResponse&lt;br /&gt;from django.core import serializers&lt;br /&gt;from list_and_detail import ListasDeReproducao&lt;br /&gt;&lt;br /&gt;class ListasDeReproducaoJson(ListasDeReproducao):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; context_object_name = 'listas_de_reproducao'&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def get(self, request, *args, **kwargs):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = serializers.serialize("json", self.get_queryset())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return HttpResponse(data, content_type='application/json')&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;O conte&amp;uacute;do desta resposta &amp;eacute; o retorno de self.get_queryset() j&amp;aacute; serializado no formato JSON. Algo como:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "pk":1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "model":"app_exemplo.listadereproducao",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "fields":{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "modificado":"2010-03-13 12:12:45",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "audios":[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "criado":"2010-01-26 15:25:26",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "titulo":"Animiais",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "slug":"Animais",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "descricao":"Alguns efeitos sonoros de animais."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "pk":2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "model":"app_exemplo.listadereproducao",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "fields":{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "modificado":"2010-05-30 08:16:53",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "audios":[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "criado":"2010-01-05 14:12:28",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "titulo":"Clicks",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "slug":"clicks",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "descricao":"Efeitos sonoros de CLICKs."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ...&lt;br class="prettyprint" /&gt;]&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Para um exemplo isto serve, mas talvez voc&amp;ecirc; realmente queira personalizar isto antes de transform&amp;aacute;-lo em Json. Por exemplo se voc&amp;ecirc; quer serializar um &lt;em&gt;queryset&lt;/em&gt; de usu&amp;aacute;rios, dependendo de como sua query foi composta, pode trazer o campo '&lt;em&gt;senha&lt;/em&gt;' e, talvez, voc&amp;ecirc; queira omit&amp;iacute;-lo deste retorno. Contudo creio que n&amp;atilde;o haver&amp;aacute; grandes problemas para fazer isto, uma vez que com &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;self.get_queryset()&lt;/code&gt; voc&amp;ecirc; consegue manipular bem estes resultados, antes de serializ&amp;aacute;-los.&lt;/p&gt;
&lt;h2&gt;&lt;a name="conclusao"&gt;&lt;/a&gt;&lt;a href="#conclusao"&gt;Conclus&amp;atilde;o&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bem, este foi um exemplo simples, em um outro artigo creio que farei algo como retornar o Json e trabalhar ele com Jquery.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a name="extra-transformando-o-retorno-em-xml"&gt;&lt;/a&gt;&lt;a href="#extra-transformando-o-retorno-em-xml"&gt;Extra:&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; quisesse, ao inv&amp;eacute;s de Json, retornar um XML, bastaria modificar duas simples coisas, neste simples exemplo, &amp;eacute; claro:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;serializers.serialize("xml", self.get_queryset())&lt;br /&gt;return HttpResponse(data, content_type='application/xml')&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/json-view-django-class-based-generic-views-iii/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/json-view-django-class-based-generic-views-iii/</feedburner:origLink></item><item><title>Programando na idade da pedra</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/9BjLvMsxEBk/</link><description>&lt;p&gt;Acho que uma grande parte dos programadores passam pelas fases iniciais do ciclo de aprendizado, cada um do seu jeito, at&amp;eacute; chegar em um ponto comum, que nos permite dizer a frase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ndash; Eu resolvo o problema!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Uns podem afirmar isto com mais convic&amp;ccedil;&amp;atilde;o que outros, mas o fato &amp;eacute; que neste momento em que eu acabei de aprender o que julgava necess&amp;aacute;rio para ser um programador, pode vir &amp;agrave; tona uma pergunta:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ndash; Estou fazendo isto certo?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ent&amp;atilde;o ap&amp;oacute;s fazer algumas buscas, conversar com algumas pessoas da &amp;aacute;rea, investigar um pouco... (voc&amp;ecirc; toma um susto!). O momento em que voc&amp;ecirc; pensa estar adiantado no tempo, quando na verdade voc&amp;ecirc; est&amp;aacute;...&lt;/p&gt;
&lt;h2&gt;...na idade da pedra&lt;/h2&gt;
&lt;p&gt;&amp;Eacute; assim que &amp;eacute; no mundo do desenvolvimento de software, se voc&amp;ecirc; deixa de praticar, ler, aprender coisas novas, ter conversas produtivas, o tempo passa. E passa mais r&amp;aacute;pido quando voc&amp;ecirc; o perde!&lt;/p&gt;
&lt;p&gt;N&amp;atilde;o somente por neglig&amp;ecirc;ncia sua. H&amp;aacute; tamb&amp;eacute;m os casos de voc&amp;ecirc; ter tantas responsabilidades, simplificando, tantos trabalhos e problemas para resolver, que acaba deixando de acompanhar a evolu&amp;ccedil;&amp;atilde;o que voc&amp;ecirc; deveria estar n&amp;atilde;o somente acompanhando, mas sim participando dela, fazendo acontecer.&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o para n&amp;atilde;o retrocedermos na evolu&amp;ccedil;&amp;atilde;o, (&lt;em&gt;programar com estaca de pedra ou tinta vegetal n&amp;atilde;o deve ser legal&lt;/em&gt;), devemos resolver o que nos impede de progredir e evoluir como profissionais e como seres humanos. (&lt;em&gt;Provavelmente precisamos evoluir mais como seres humanos primeiro, mas n&amp;atilde;o &amp;eacute; bem minha &amp;aacute;rea para entrarmos neste assunto.&lt;/em&gt;)&lt;/p&gt;
&lt;h2&gt;Viva o aprendizado cont&amp;iacute;nuo&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Leia, assista, escute, estude...&lt;/li&gt;
&lt;li&gt;Participe de grupos que discutem assuntos de seu interesse.&lt;/li&gt;
&lt;li&gt;Procure fazer o que lhe traz alegria e satisfa&amp;ccedil;&amp;atilde;o, assim voc&amp;ecirc; fica muito bom no que faz e o dinheiro vir&amp;aacute; com certeza!&lt;/li&gt;
&lt;li&gt;Programar n&amp;atilde;o se trata apenas de digitar instru&amp;ccedil;&amp;otilde;es para uma m&amp;aacute;quina, use a criatividade e escreva para seres humanos n&amp;atilde;o para m&amp;aacute;quinas.&lt;/li&gt;
&lt;li&gt;Compartilhe o seu conhecimento.&lt;/li&gt;
&lt;li&gt;Relaxe! H&amp;aacute; momentos em que voc&amp;ecirc; precisa descansar ou mesmo praticar o seu hobby preferido.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parece at&amp;eacute; que foi um texto sobre mim, mas n&amp;atilde;o necessariamente, pois sou meio estranho desde o in&amp;iacute;cio sempre tive esses surtos de que estou a anos luz de atingir o conhecimento que queria ter.&lt;/p&gt;
&lt;p&gt;Na verdade, hoje em dia, estou aprendendo a controlar estes impulsos de querer absorver tudo de uma vez e estou indo por partes, assim n&amp;atilde;o paro de evoluir, mantenho uma "dieta de consumo de conte&amp;uacute;do" agrad&amp;aacute;vel e estou conseguindo me organizar cada vez mais, e isto &amp;eacute; bom.&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o n&amp;atilde;o mantenha sua mente na idade da pedra. Evolua hoje, evolua j&amp;aacute; e evolua sempre!&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/programando-na-idade-da-pedra/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/programando-na-idade-da-pedra/</feedburner:origLink></item><item><title>DetailView - Django class-based generic views - II</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/dHTVNzJbsAg/</link><description>&lt;h2&gt;&lt;a name="introducao"&gt;&lt;/a&gt;&lt;a href="#introducao"&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Quando precisamos listar os detalhes de um objeto que, geralmente, est&amp;aacute; em um banco de dados, n&amp;oacute;s encontramos e selecionamos ele pela sua chave prim&amp;aacute;ria &lt;em&gt;&lt;strong&gt;(pk)&lt;/strong&gt;&lt;/em&gt; ou mesmo pelo &lt;a href="https://docs.djangoproject.com/en/dev/glossary/#term-slug" target="_blank"&gt;&lt;strong&gt;&lt;em&gt;(slug)&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;. Vamos ver como fazer isto com a classe DetailView do Django.&lt;/p&gt;
&lt;p&gt;Para uma melhor intera&amp;ccedil;&amp;atilde;o do usu&amp;aacute;rio para/com a aplica&amp;ccedil;&amp;atilde;o, geralmente, n&amp;atilde;o esperamos que ele saiba de cabe&amp;ccedil;a a url para acessar os detalhes de um objeto, por isso criamos sempre uma listagem de objetos contendo os links para acessar mais informa&amp;ccedil;&amp;otilde;es sobre os mesmos. Esta listagem de objetos &amp;eacute; abordada no primeiro artigo dessa s&amp;eacute;rie de artigos sobre &lt;strong&gt;class-based generic views&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;De fato, ser&amp;aacute; bom se voc&amp;ecirc; ler, ao menos, o trecho introdut&amp;oacute;rio do artigo &lt;a href="/artigo/listview-django-class-based-generic-views-i/#class-based-generic-views" target="_blank"&gt;ListView - Django class-based generic views - I&lt;/a&gt; para entender o exemplo que estou usando para fazer as views desta s&amp;eacute;rie de artigos.&lt;/p&gt;
&lt;h2&gt;&lt;a name="detailview"&gt;&lt;/a&gt;&lt;a href="#detailview"&gt;DetailView - listando as informa&amp;ccedil;&amp;otilde;es de um objeto&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Vamos listar as listas de reprodu&amp;ccedil;&amp;atilde;o que est&amp;atilde;o cadastradas minha base de dados. Para isto s&amp;oacute; precisamos importar, dentro de &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/span&gt;, o meu model e a classe &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt;. Como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="kwd"&gt;from&lt;/span&gt;&lt;span class="pln"&gt; django&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;views&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;generic &lt;/span&gt;&lt;span class="kwd"&gt;import&lt;/span&gt;&lt;span class="pln"&gt; DetailView&lt;/span&gt;&lt;br /&gt;&lt;span class="kwd"&gt;from&lt;/span&gt;&lt;span class="pln"&gt; app_exemplo&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;models &lt;/span&gt;&lt;span class="kwd"&gt;import&lt;/span&gt;&lt;span class="typ"&gt;ListaDeReproducao&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="typ"&gt; DetalhesListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;DetailView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; model &lt;/span&gt;&lt;span class="pun"&gt;= &lt;/span&gt;&lt;span class="typ"&gt;ListaDeReproducao&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Bem f&amp;aacute;cil! No template, por padr&amp;atilde;o, far&amp;iacute;amos assim:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;listadereproducao_detail.html&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="tag"&gt;&amp;lt;h1&amp;gt;{{ listadereproducao.titulo }}&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;{{ listadereproducao.descricao }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Criada: &amp;lt;strong&amp;gt;{{ listadereproducao.criado }}&amp;lt;/strong&amp;gt; |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Atualizada: &amp;lt;strong&amp;gt;{{ listadereproducao.modificado }}&amp;lt;/strong&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;NOTE: &lt;br /&gt;Abaixo eu listo todos os arquivos de &amp;aacute;udio pertencentes &amp;agrave; minha "Lista de reprodu&amp;ccedil;&amp;atilde;o".&lt;br /&gt;Para entender melhor a composi&amp;ccedil;&amp;atilde;o do meu model ListaDeReprodu&amp;ccedil;&amp;atilde;o, visite:&lt;br /&gt;&lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/blob/master/projeto/app_exemplo/models.py" target="_blank"&gt;app_exemplo/models.py&lt;/a&gt;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;{% for audio in listadereproducao.audios.all %}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&amp;lt;a href="{{ MEDIA_URL }}{{ audio.audio }}"&amp;gt;{{ audio.titulo }}&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;{{ audio.descricao }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&amp;Uacute;ltima atualiza&amp;ccedil;&amp;atilde;o: {{ audio.modificado|timesince }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/li&amp;gt;&lt;br /&gt;{% endfor %}&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name="personalizando-detailview"&gt;&lt;/a&gt;&lt;a href="#personalizando-detailview"&gt;Personalizando a DetailView&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Para fazer mais com &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt; podemos personalizar outros atributos que t&amp;ecirc;m valores padr&amp;atilde;o mas que podemos alter&amp;aacute;-los e manipul&amp;aacute;-los. Vamos ver os principais:&lt;/p&gt;
&lt;h4&gt;&lt;a name="template_name"&gt;&lt;/a&gt;&lt;a href="#template_name"&gt;template_name&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A personaliza&amp;ccedil;&amp;atilde;o deste atributo &amp;eacute; feita da mesma forma que no ListView, veja mais na view &lt;a href="/admin/blog/artigo/24/douglasmiranda.com/artigo/listview-django-class-based-generic-views-i/#class-based-generic-views" target="_blank"&gt;ListasDeReproducao&lt;/a&gt;. O que muda &amp;eacute; que se voc&amp;ecirc; n&amp;atilde;o definir, automaticamente ela vai buscar o seguinte template: &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;listadereproducao_detail.html&lt;/em&gt;&lt;/span&gt; que &amp;eacute; a soma do nome do Model + o tipo de view: Model: &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListaDeReproducao&lt;/code&gt; e View: &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para informar a localiza&amp;ccedil;&amp;atilde;o do template com o nome personalizado basta fazer como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; DetalhesListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;DetailView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; template_name &lt;/span&gt;&lt;span class="pun"&gt;= &lt;/span&gt;&lt;span class="str"&gt;'app_exemplo/lista_de_reproducao_detalhes.html'&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="queryset"&gt;&lt;/a&gt;&lt;a href="#queryset"&gt;queryset&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Como no &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt; aqui voc&amp;ecirc; pode escolher entre fornecer o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;model&lt;/code&gt; e/ou o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;queryset&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Mas manipular &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;queryset&lt;/code&gt; no &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt; seria para casos bem espec&amp;iacute;ficos, pois filtragem e outras coisas que podem ser feitas com o queryset s&amp;atilde;o geralmente feitas j&amp;aacute; na hora de listar, no caso, em uma &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt; e no &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt; o objeto selecionado j&amp;aacute; &amp;eacute; o definitivo e queremos somente extrair informa&amp;ccedil;&amp;otilde;es dele. Para fazer maiores personaliza&amp;ccedil;&amp;otilde;es no objeto de contexto gerado pela &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt; &amp;eacute; necess&amp;aacute;rio manipular os objetos de contexto com o m&amp;eacute;todo &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get_context_data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; DetalhesListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;DetailView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; queryset &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="typ"&gt; ListaDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;objects&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;all&lt;/span&gt;&lt;span class="pun"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="context_object_name"&gt;&lt;/a&gt;&lt;a href="#context_object_name"&gt;context_object_name&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Se voc&amp;ecirc; n&amp;atilde;o der um nome para o objeto de contexto para manipular nos templates o nome dele ser&amp;aacute; o nome do model, neste caso &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;listadereproducao&lt;/code&gt;, em &lt;em&gt;lower case&lt;/em&gt; mesmo. Ou poder&amp;aacute; ser acessado, tamb&amp;eacute;m, como &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;object&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; visualizar as vari&amp;aacute;veis de contexto que est&amp;atilde;o sendo passadas para seu template ver&amp;aacute; algo assim:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'listadereproducao': &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'object': &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;&lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Voc&amp;ecirc; pode personaliz&amp;aacute;-lo como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; DetalhesListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;DetailView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; context_object_name = 'lista_de_reproducao'&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="note-sobre-objetos-de-contexto"&gt;&lt;/a&gt;&lt;a href="#note-sobre-objetos-de-contexto"&gt;NOTE: Sobre Objetos de contexto&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;O objeto de contexto na &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;DetailView&lt;/code&gt; &amp;eacute; diferente da &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt;, pois no conte&amp;uacute;do extra&amp;iacute;do do Model n&amp;atilde;o temos uma lista e sim um objeto, j&amp;aacute; que a inten&amp;ccedil;&amp;atilde;o &amp;eacute; listar os detalhes de um objeto espec&amp;iacute;fico.&lt;/p&gt;
&lt;p&gt;N&amp;atilde;o quer dizer que voc&amp;ecirc; n&amp;atilde;o possa definir o m&amp;eacute;todo &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get_context_data&lt;/code&gt; e personalizar os objetos de contexto:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;from models import OutroModel&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; DetalhesListasDeReproducao&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="typ"&gt;DetailView&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="com"&gt;# ...&lt;/span&gt;&lt;br /&gt;&lt;span class="pln"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def get_context_data(self, **kwargs):&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;context = super(DetalhesListasDeReproducao, self).get_context_data(**kwargs)&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;# Aqui voc&amp;ecirc; far&amp;aacute; inclus&amp;atilde;o, altera&amp;ccedil;&amp;atilde;o ou exclus&amp;atilde;o de contextos como desejar&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # por exemplo, agora estou adicionando mais um objeto de contexto&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;context['listas_de_outras_coisas'] = OutroModel.objects.all()&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return context&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name="conclusao-e-links"&gt;&lt;/a&gt;&lt;a href="#conclusao-e-links"&gt;Conclus&amp;atilde;o&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ent&amp;atilde;o &amp;eacute; isto, quaisquer d&amp;uacute;vidas, cr&amp;iacute;ticas e sugest&amp;otilde;es fa&amp;ccedil;am nos coment&amp;aacute;rios e/ou issues no reposit&amp;oacute;rio do projeto no github. Que a prop&amp;oacute;sito voc&amp;ecirc; pode acompanhar o reposit&amp;oacute;rio "&lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/" target="_blank"&gt;django-class-based-generic-views&lt;/a&gt;" e pode visualizar o exemplo que abordei aqui em &lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/blob/master/projeto/app_exemplo/views/list_and_detail.py" target="_blank"&gt;projeto / app_exemplo / views / list_and_detail.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At&amp;eacute; o pr&amp;oacute;ximo artigo!&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/detailview-django-class-based-generic-views-ii/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/detailview-django-class-based-generic-views-ii/</feedburner:origLink></item><item><title>ListView - Django class-based generic views - I</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/KbmDJ7r5iNw/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Nosso arquivo &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/span&gt; pode ficar mais elegante e leg&amp;iacute;vel e escrever views pode se tornar uma tarefa trivial para implementa&amp;ccedil;&amp;otilde;es simples. &lt;strong&gt;#AskMeHow&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name="class-based-generic-views"&gt;&lt;/a&gt;&lt;a href="#class-based-generic-views"&gt;Class-based generic views&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Antes havia as generic views que eram baseadas em fun&amp;ccedil;&amp;otilde;es, mas a partir do Django 1.3 est&amp;aacute; dispon&amp;iacute;vel as&lt;a href="https://docs.djangoproject.com/en/1.3/ref/class-based-views/" target="_blank"&gt; class-based generic views&lt;/a&gt; e assim podemos definir atributos, comportamentos e caracter&amp;iacute;sticas especiais em nossas views de modo mais elegante, reaproveit&amp;aacute;vel e intelig&amp;iacute;vel.&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o farei uma s&amp;eacute;rie de artigos aqui em meu blog, cobrindo as principais formas de uso desse &amp;oacute;timo recurso do Django. Para isto criei um &lt;a title="V&amp;aacute; para o reposit&amp;oacute;rio 'Django Class-Based Generic Views'" href="https://github.com/douglasmiranda/django-class-based-generic-views" target="_blank"&gt;reposit&amp;oacute;rio&lt;/a&gt; em &lt;a href="https://github.com/douglasmiranda/" target="_blank"&gt;meu github&lt;/a&gt; com um projeto simples, com uma app para criar as views para ela e assim ter o conte&amp;uacute;do pr&amp;aacute;tico do que estarei explicando nos artigos.&lt;/p&gt;
&lt;p&gt;Vamos come&amp;ccedil;ar a s&amp;eacute;rie de artigos com um dos tipos de views que mais utilizo no meu dia-a-dia como desenvolvedor, &amp;eacute; a ListView. Levando em considera&amp;ccedil;&amp;atilde;o que meu arquivo &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/span&gt; &amp;eacute; &lt;a title="models.py contendo os models para os exemplos nas views" href="https://github.com/douglasmiranda/django-class-based-generic-views/blob/master/projeto/app_exemplo/models.py" target="_blank"&gt;este em meu reposit&amp;oacute;rio&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;&lt;a name="listview"&gt;&lt;/a&gt;&lt;a href="#listview"&gt;ListView - listagem de objetos de um model&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Vamos listar as listas de reprodu&amp;ccedil;&amp;atilde;o que est&amp;atilde;o cadastradas minha base de dados. Para isto s&amp;oacute; precisamos importar, dentro de &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/span&gt;, o meu model e a classe &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt;. Como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;from django.views.generic import ListView&lt;br /&gt;from app_exemplo.models import ListaDeReproducao&lt;br /&gt;&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; model = ListaDeReproducao&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Simples n&amp;atilde;o? E meu template, por padr&amp;atilde;o, ficaria assim:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;listadereproducao_list.html&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;{% for lista_de_reproducao in object_list %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&amp;lt;a href="{{ lista_de_reproducao.get_absolute_url }}"&amp;gt;{{ lista_de_reproducao.titulo }}&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;{{ lista_de_reproducao.descricao }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/li&amp;gt;&lt;br /&gt;{% endfor %}&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name="personalizando-listview"&gt;&lt;/a&gt;&lt;a href="#personalizando-listview"&gt;Personalizando a ListView&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Podemos fazer muito mais com &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt; utilizando e personalizando outros atributos que t&amp;ecirc;m valores padr&amp;atilde;o mas que podemos alterar e manipul&amp;aacute;-los. Vamos ver os principais:&lt;/p&gt;
&lt;h4&gt;&lt;a name="template_name"&gt;&lt;/a&gt;&lt;a href="#template_name"&gt;template_name&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Voc&amp;ecirc; pode usar o atributo &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;template_name&lt;/code&gt; para informar a localiza&amp;ccedil;&amp;atilde;o do template personalizado que voc&amp;ecirc; quer utilizar.&lt;/p&gt;
&lt;p&gt;Caso n&amp;atilde;o queira informar, que &amp;eacute; o que eu fiz aqui, por padr&amp;atilde;o o Django tentar&amp;aacute; encontrar um template com um nome neste padr&amp;atilde;o: &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;NomeDoModel_TipoDeView.html&lt;/em&gt;&lt;/span&gt;. Como o nosso model &amp;eacute; o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListaDeReproducao&lt;/code&gt; e nossa view &amp;eacute; uma &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt; ele buscar&amp;aacute; por:&lt;span style="text-decoration: underline;"&gt;&lt;em&gt; listadereproducao_list.html&lt;/em&gt;&lt;/span&gt;. Voc&amp;ecirc; pode conferir em: &lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/tree/master/projeto/app_exemplo/templates/app_exemplo" target="_blank"&gt;&lt;em&gt;app_exemplo/templates/app_exemplo/&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Para informar a localiza&amp;ccedil;&amp;atilde;o do template com o nome personalizado basta fazer como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; template_name = 'app_exemplo/lista_de_reproducao.html'&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="queryset"&gt;&lt;/a&gt;&lt;a href="#queryset"&gt;queryset&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Um outro atributo que pode substituir o model &amp;eacute; o queryset. Com ele &amp;eacute; poss&amp;iacute;vel passar a lita de objetos a serem listados. A vantagem &amp;eacute; que voc&amp;ecirc; j&amp;aacute; pode personalizar a recupera&amp;ccedil;&amp;atilde;o desses dados, informando por exemplo um .filter(), .order(), entre outros m&amp;eacute;todos dispon&amp;iacute;veis no model. Dessa forma:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; queryset = ListaDeReproducao.objects.all()&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="context_object_name"&gt;&lt;/a&gt;&lt;a href="#context_object_name"&gt;context_object_name&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;O &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;context_object_name&lt;/code&gt; &amp;eacute; o nome da vari&amp;aacute;vel de contexto que estar&amp;aacute; dispon&amp;iacute;vel para voc&amp;ecirc; manipular em seu template, em nosso caso no &lt;span style="text-decoration: underline;"&gt;&lt;em&gt;listadereproducao_list.html&lt;/em&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; n&amp;atilde;o informa um nome personalizado, que foi o que fizemos, a vari&amp;aacute;vel vai se chamar &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;object_list&lt;/code&gt; que ser&amp;aacute; uma lista de objetos. Ela tamb&amp;eacute;m poder&amp;aacute; ser chamada por um nome composto da seguinte maneira: &lt;em&gt;NOME_DO_MODEL_list&lt;/em&gt;, em nosso caso &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;listadereproducao_list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para representar visualmente, em nosso exemplo ser&amp;aacute; algo como isto:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # OUTROS OBJETOS DE CONTEXTO,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'object_list':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&amp;lt;ListaDeReproducao: Animiais&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Clicks&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Sons de armas (GERAL)&amp;gt;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'listadereproducao_list':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&amp;lt;ListaDeReproducao: Animiais&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Clicks&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Sons de armas (GERAL)&amp;gt;]&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Podemos manipular, por exemplo, assim:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;{% for lista_de_reproducao in object_list %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;{{ lista_de_reproducao.titulo }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;{{ lista_de_reproducao.descricao }}&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/li&amp;gt;&lt;br /&gt;{% endfor %}&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o se quisermos que &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;object_list&lt;/code&gt; vire, por exemplo, &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;listas_de_reproducao&lt;/code&gt; fa&amp;ccedil;a como no exemplo abaixo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; context_object_name = 'listas_de_reproducao'&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;&lt;a name="get_context_data"&gt;&lt;/a&gt;&lt;a href="#get_context_data"&gt;NOTE: Sobre objetos de contexto&lt;/a&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;Se voc&amp;ecirc; quiser obter o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;context_object_name&lt;/code&gt; ou o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;queryset&lt;/code&gt;, voc&amp;ecirc; poderia simplesmente usar dos m&amp;eacute;todos: &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get_context_object_name&lt;/code&gt;, &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get_queryset&lt;/code&gt; que podem ser encontrados, para melhor visualiza&amp;ccedil;&amp;atilde;o, em django/views/generic/list.py.&lt;/p&gt;
&lt;p&gt;Caso queira fazer mais do que apenas obter, se quizer, em algum momento modificar, tratar casos espec&amp;iacute;ficos ou mesmo deixar mais expl&amp;iacute;cito os objetos de contexto que estar&amp;atilde;o dispon&amp;iacute;veis em seu template, voc&amp;ecirc; pode utilizar o &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;get_context_data&lt;/code&gt;, como no exemplo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def get_context_data(self, **kwargs):&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;context = super(ListasDeReproducao, self).get_context_data(**kwargs)&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;# Aqui voc&amp;ecirc; far&amp;aacute; inclus&amp;atilde;o, altera&amp;ccedil;&amp;atilde;o ou exclus&amp;atilde;o de contextos como desejar&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;context['ultima_lista_de_reproducao'] = ListaDeReproducao.objects.latest()&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return context&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Se quiser saber em tempo de execu&amp;ccedil;&amp;atilde;o quais os objetos de contexto que est&amp;atilde;o sendo passados para seu template, voc&amp;ecirc; pode definir este m&amp;eacute;todo e mandar imprimir em console para que voc&amp;ecirc; possa ver assim que acessar a url.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def get_context_data(self, **kwargs):&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context = super(ListasDeReproducao, self).get_context_data(**kwargs)&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # imprimindo no console o que h&amp;aacute; no dicion&amp;aacute;rio de contextos&lt;br /&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print context&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Voc&amp;ecirc; ver&amp;aacute; algo desse tipo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'paginator': None,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'page_obj': None,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'is_paginated': False,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'object_list':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&amp;lt;ListaDeReproducao: Animiais&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Clicks&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Sons de armas (GERAL)&amp;gt;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'listadereproducao_list':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&amp;lt;ListaDeReproducao: Animiais&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Clicks&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Armas disparando&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ListaDeReproducao: Sons de armas (GERAL)&amp;gt;]&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a name="paginate_by"&gt;&lt;/a&gt;&lt;a href="#paginate_by"&gt;paginate_by - Pagina&amp;ccedil;&amp;atilde;o&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Toda lista de objetos tende a aumentar, para isto precisamos controlar a exibi&amp;ccedil;&amp;atilde;o desses objetos em tela com a pagina&amp;ccedil;&amp;atilde;o. Para isto basta fornecer ao atributo &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;paginate_by&lt;/code&gt; a quantidade de objetos que voc&amp;ecirc; quer que seja listada por p&amp;aacute;gina. Por exemplo, &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;paginate_by = 4&lt;/code&gt;,&amp;nbsp; listar&amp;aacute; 15 objetos por p&amp;aacute;gina. Se quiser ver isto em funcionamento, fa&amp;ccedil;a algo assim:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; paginate_by = 2&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No template, em um exemplo bem simples de p&amp;aacute;gina&amp;ccedil;&amp;atilde;o voc&amp;ecirc; poderia fazer, como fiz no exemplo, algo como:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;{% if is_paginated %}&lt;br /&gt;&amp;lt;div class="paginacao"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span class="paginacao-links"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {% if page_obj.has_previous %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href="?page={{ page_obj.previous_page_number }}"&amp;gt;anterior&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {% endif %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span class="page-current"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; P&amp;amp;aacute;gina {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {% if page_obj.has_next %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href="?page={{ page_obj.next_page_number }}"&amp;gt;pr&amp;amp;oacute;xima&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {% endif %}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;{% endif %}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Que ter&amp;aacute; como resultado algo como: "P&amp;aacute;gina 1 de 2. pr&amp;oacute;xima"&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;&lt;a name="personalizando-paginacao"&gt;&lt;/a&gt;&lt;a href="#personalizando-paginacao"&gt;NOTE: Sobre pagina&amp;ccedil;&amp;atilde;o&lt;/a&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;A criatividade &amp;eacute; bastante aplicada neste ponto, ent&amp;atilde;o voc&amp;ecirc; al&amp;eacute;m de explorar as op&amp;ccedil;&amp;otilde;es de personaliza&amp;ccedil;&amp;atilde;o do template pode alterar conforme quiser o limite desta pagina&amp;ccedil;&amp;atilde;o inclusive em tempo de execu&amp;ccedil;&amp;atilde;o com o "paginate_queryset". No exemplo abaixo exemplifico isto, tentando obter da url o par&amp;acirc;metro &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;limite&lt;/code&gt; para ser usado como pagina&amp;ccedil;&amp;atilde;o, caso n&amp;atilde;o exista eu uso a pagina&amp;ccedil;&amp;atilde;o padr&amp;atilde;o.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;# ...&lt;br /&gt;class ListasDeReproducao(ListView):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def paginate_queryset(self, queryset, page_size):&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page_size = self.request.GET.get('limite', page_size)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; paginate_queryset = super(ListasDeReproducao, self).paginate_queryset(queryset, page_size)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return paginate_queryset&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Conclus&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Ent&amp;atilde;o &amp;eacute; isto, quaisquer d&amp;uacute;vidas, cr&amp;iacute;ticas e sugest&amp;otilde;es fa&amp;ccedil;am nos coment&amp;aacute;rios e/ou issues no reposit&amp;oacute;rio do projeto no github. Que a prop&amp;oacute;sito voc&amp;ecirc; pode acompanhar o reposit&amp;oacute;rio "&lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/" target="_blank"&gt;django-class-based-generic-views&lt;/a&gt;" e pode visualizar o exemplo que abordei aqui em &lt;a href="https://github.com/douglasmiranda/django-class-based-generic-views/blob/master/projeto/app_exemplo/views/list_and_detail.py" target="_blank"&gt;projeto / app_exemplo / views / list_and_detail.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;O pr&amp;oacute;ximo artigo ser&amp;aacute; sobre DetailView.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; J&amp;aacute; h&amp;aacute; o artigo sobre DetailView, confiram: &lt;a href="/artigo/detailview-django-class-based-generic-views-ii/"&gt;DetailView - Django class-based generic views - II&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE2 (28/05/2012):&lt;/strong&gt; Em um novo artigo eu estendi esta &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;ListView&lt;/code&gt; e criei um &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;JsonView&lt;/code&gt;, confira em: &lt;a href="/artigo/json-view-django-class-based-generic-views-iii/"&gt;Json View - Django class-based generic views - III &lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/listview-django-class-based-generic-views-i/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/listview-django-class-based-generic-views-i/</feedburner:origLink></item><item><title>Outra perspectiva sobre escalabilidade - sobre humanos, não robôs</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/8IYVVWridjQ/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Sabemos que sistemas escal&amp;aacute;veis devem ser capazes de suportar o pr&amp;oacute;prio crescimento sem ceder em nenhum aspecto em nenhum momento. Para tal devemos investir milhares ou milh&amp;otilde;es de nosso capital financeiro em solu&amp;ccedil;&amp;otilde;es prontas ou sob medida que o mercado ou nossa equipe tem a oferecer. At&amp;eacute; agora, tudo ok!&lt;/p&gt;
&lt;p&gt;Recentemente estava vendo uns slides de &lt;a href="http://zachholman.com/" target="_blank"&gt;Zach Holman&lt;/a&gt; (&lt;a href="http://speakerdeck.com/u/holman/p/scaling-github" target="_blank"&gt;Scaling GitHub&lt;/a&gt;) e me deparei com um fator ligado &amp;agrave; escalabilidade de sistemas que eu n&amp;atilde;o tinha parado para pensar ainda, nem quando comecei fazer minha monografia sobre escalabilidade em aplica&amp;ccedil;&amp;otilde;es web. Este fator &amp;eacute; o "fator humano".&lt;/p&gt;
&lt;h2&gt;O fator humano na escalabilidade de sistemas&lt;/h2&gt;
&lt;p&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/scaling-people_technology_large.png" alt="Scaling is people + tecnhnology" width="680" height="86" /&gt;&lt;/p&gt;
&lt;p&gt;Algo que tem grande influ&amp;ecirc;ncia sobre os fatores t&amp;eacute;cnicos ligados &amp;agrave; escalabilidade &amp;eacute; quem tomar&amp;aacute; as decis&amp;otilde;es sobre a parte t&amp;eacute;cnica, quem implementar&amp;aacute;, quem far&amp;aacute; acontecer, ou seja, os membros de sua equipe. Sejam estes os lideres, gerentes, desenvolvedores ou mesmo quem faz o caf&amp;eacute;.&lt;/p&gt;
&lt;h3&gt;Felicidade&lt;/h3&gt;
&lt;p&gt;&lt;img class="img_left" src="http://media.douglasmiranda.com/uploads/artigos/smile.png" alt="Felicidade" width="254" height="222" /&gt;&lt;/p&gt;
&lt;p&gt;Os membros da equipe precisam estar felizes, em sintonia e os lideres mais ainda talvez. A felicidade aumenta a produtividade e a produtividade aumenta a felicidade.&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o os colaboradores j&amp;aacute; existentes em nossa startup, grande companhia ou software house precisam, al&amp;eacute;m de capacita&amp;ccedil;&amp;atilde;o e dedica&amp;ccedil;&amp;atilde;o, de estar bem com o ambiente de trabalho, com os colegas e certamente bem em sua vida pessoal.&lt;/p&gt;
&lt;p class="clearfix"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Contrate mais pessoas / N&amp;atilde;o contrate mais pessoas&lt;/h3&gt;
&lt;p&gt;&lt;img class="img_right" src="http://media.douglasmiranda.com/uploads/artigos/contratar-nao-contratar.png" alt="Contratar ou n&amp;atilde;o contratar...?" width="293" height="236" /&gt;&lt;/p&gt;
&lt;p&gt;Contratar novas pessoas pode ser a melhor ou pior coisa que voc&amp;ecirc; faz ao seu projeto.&lt;/p&gt;
&lt;p&gt;Voc&amp;ecirc; deve analisar n&amp;atilde;o somente se h&amp;aacute; dinheiro em caixa e se o candidato &amp;eacute; capacitado. H&amp;aacute; tamb&amp;eacute;m a preocupa&amp;ccedil;&amp;atilde;o de verificar se nesse momento em que voc&amp;ecirc; quer escalar seu neg&amp;oacute;cio &amp;eacute;, realmente, necess&amp;aacute;rio uma equipe maior, pois quanto maior, mais trabalho para acompanhar, gerenciar. Leva tempo at&amp;eacute; a adapta&amp;ccedil;&amp;atilde;o, muitas vezes um investimento a longo prazo.&lt;/p&gt;
&lt;p&gt;Por outro lado, haver&amp;aacute; mais mentes pensando, mais solu&amp;ccedil;&amp;otilde;es surgindo, aumento na cultura. E com o tempo mais agilidade, menos bugs e vai escalar melhor, mas tudo isto, s&amp;oacute; se acertarmos na contrata&amp;ccedil;&amp;atilde;o.&lt;/p&gt;
&lt;h3&gt;Uma cultura de Fil&amp;oacute;sofos / Especialistas&lt;/h3&gt;
&lt;p class="clearfix"&gt;Claro que parece absurda esta ideia, pois &amp;eacute; contradit&amp;oacute;ria. Fil&amp;oacute;sofos sempre abrangem as coisas para entender o mundo como um todo e especialistas creem e afirmam somente aquilo que realmente sabem que est&amp;aacute; no seu campo de conhecimento espec&amp;iacute;fico.&lt;/p&gt;
&lt;p&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/wrong.png" alt="Wrong!" width="272" height="219" /&gt;&lt;/p&gt;
&lt;p&gt;Possua os melhores em cada &amp;aacute;rea, trabalhando no que gostam e como gostam para melhores resultados, mas n&amp;atilde;o centralize. Se voc&amp;ecirc; tem o ninja do banco de dados, talvez seja bom que outro ou outros conhe&amp;ccedil;am o trabalho desse ninja, caso em algum momento ele n&amp;atilde;o esteja mais no projeto, voc&amp;ecirc; conhecia e agora sabe o que fazer na aus&amp;ecirc;ncia do ninja at&amp;eacute; alocar outro.&lt;/p&gt;
&lt;p class="clearfix"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Aprendizado Cont&amp;iacute;nuo e Motiva&amp;ccedil;&amp;atilde;o&lt;/h3&gt;
&lt;p&gt;Crie um ambiente de aprendizado cont&amp;iacute;nuo para os colaboradores, seja enviando-os para eventos, investindo na especializa&amp;ccedil;&amp;atilde;o deles, ajudando-os em projetos pessoais, permitindo a voz ativa para sugest&amp;otilde;es.&lt;/p&gt;
&lt;p&gt;Motiva&amp;ccedil;&amp;atilde;o &amp;eacute; um termo antigo, muito discutido e todos n&amp;oacute;s sabemos v&amp;aacute;rios aspectos sobre isto, mas busque analisar sua equipe para encontrar quais s&amp;atilde;o os fatores motivacionais que podem melhorar a produtividade, trazendo retorno para o projeto e para todos envolvidos. Imagine como um relacionamento em que voc&amp;ecirc; est&amp;aacute; a todo momento tentando descobrir o que a outra pessoa precisa para ser feliz e assim seguir adiante sem maiores problemas, mas isto tem de ser rec&amp;iacute;proco.&lt;/p&gt;
&lt;h2&gt;Conclus&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Ent&amp;atilde;o no momento em que formos pensar em escalar nosso empreendimento/software/projeto, devemos dar uma aten&amp;ccedil;&amp;atilde;o mais que especial ao fator humano, que talvez assim at&amp;eacute; teremos uma ajuda melhor para escolher qual plano da AmazonWS contrataremos.&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/outra-perspectiva-sobre-escalabilidade-sobre-humanos-nao-robos/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/outra-perspectiva-sobre-escalabilidade-sobre-humanos-nao-robos/</feedburner:origLink></item><item><title>Coisas que aprendi com desenvolvimento de software: Escrever</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/cwXk630V_o0/</link><description>&lt;h2&gt;Escrever, mas n&amp;atilde;o escrever somente c&amp;oacute;digos!&lt;/h2&gt;
&lt;p&gt;Voc&amp;ecirc; sabe programar. Uma afirma&amp;ccedil;&amp;atilde;o, ok! Mas sabe explicar o que acabou de fazer? Voc&amp;ecirc; j&amp;aacute; aprendeu isto h&amp;aacute; muito tempo quando os professores na escola lhe perguntavam algo que voc&amp;ecirc; sabia, s&amp;oacute; n&amp;atilde;o sabia se expressar corretamente para explicar com palavras. Isto quando era somente para escrever, pois se fosse oralmente, &amp;agrave;s vezes era mais dif&amp;iacute;cil ainda.&lt;/p&gt;
&lt;p&gt;Saber explicar o que voc&amp;ecirc; acabou de fazer, n&amp;atilde;o &amp;eacute; somente &amp;uacute;til se voc&amp;ecirc; tiver de escrever algum artigo ou explicar para algu&amp;eacute;m, &amp;eacute; tamb&amp;eacute;m uma forma de aprender, e n&amp;atilde;o somente decorar.&lt;/p&gt;
&lt;p&gt;Se est&amp;aacute; dif&amp;iacute;cil de explicar, talvez seja necess&amp;aacute;rio documentar esta parte do software e como voc&amp;ecirc; o far&amp;aacute; se n&amp;atilde;o sabe explicar. Coment&amp;aacute;rios incompreens&amp;iacute;veis s&amp;atilde;o in&amp;uacute;teis.&lt;/p&gt;
&lt;p&gt;O que os professores nos dizem ao apresentarem Orienta&amp;ccedil;&amp;atilde;o &amp;agrave; Objetos (OO)?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] &amp;eacute; um paradigma de programa&amp;ccedil;&amp;atilde;o que vai trazer aspectos do mundo real para o desenvolvimento de software, tornando melhor o reaproveitamento de c&amp;oacute;digo, [...], e &lt;strong&gt;fazendo com que o c&amp;oacute;digo fique mais organizado e f&amp;aacute;cil de entender&lt;/strong&gt;.&lt;br /&gt;&lt;em&gt;-- Professores&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Se programar com OO tem como um dos objetivos deixar o c&amp;oacute;digo mais intelig&amp;iacute;vel, como eu serei capaz de fazer isto se n&amp;atilde;o entender perfeitamente o problema a fim de escrever um algoritmo que expresse de forma objetiva a solu&amp;ccedil;&amp;atilde;o do meu problema, e o mais importante, que eu e outras pessoas que analisem o c&amp;oacute;digo consigam compreender o que acabei de fazer?&lt;/p&gt;
&lt;p&gt;Para isto tenho de ser capaz de explicar isto claramente para mim e para outras pessoas, afinal, atualmente n&amp;atilde;o desenvolvemos software sozinhos, e o software n&amp;atilde;o "vive" somente enquanto eu viver, ent&amp;atilde;o melhor fazermos com que as pessoas guardem sentimentos bons de n&amp;oacute;s e n&amp;atilde;o raiva por deixar um c&amp;oacute;digo horr&amp;iacute;vel como heran&amp;ccedil;a. (&lt;em&gt;Acho que fui fundo nesse trecho, n&amp;atilde;o?&lt;/em&gt;).&lt;/p&gt;
&lt;h2&gt;Escrever para compartilhar =]&lt;/h2&gt;
&lt;p&gt;E a parte legal disso, a parte que foge da obriga&amp;ccedil;&amp;atilde;o, &amp;eacute; quando vamos escrever por livre e espont&amp;acirc;nea vontade. Com o objetivo de passar o conhecimento a frente, com o objetivo de propagar o conhecimento livre para todos. Ent&amp;atilde;o leia, &lt;strong&gt;escreva&lt;/strong&gt;, e compartilhe. O seu conhecimento &amp;eacute; um bem inestim&amp;aacute;vel, que somente n&amp;oacute;s leitores somos capazes de saber o valor dele.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It's always more fun. To share with everyone.&lt;br /&gt;-- Jack Johnson&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Conclus&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;&amp;Eacute; isto, aprendi que escrever &amp;eacute; mais legal do que a gente aprende na escola e aprendi isto com desenvolvimento de software. Para estimular seu conhecimento a fim de estar apto a escrever bem leia, leia muito, esta &amp;eacute; tamb&amp;eacute;m uma coisa que aprendi e comento no artigo desta mesma sess&amp;atilde;o: &lt;a href="/artigo/coisas-que-aprendi-com-desenvolvimento-de-software-leitura/"&gt;Coisas que aprendi com desenvolvimento de software: &lt;strong&gt;Leitura&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Obrigado, e espero que tenham gostado!&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/coisas-que-aprendi-com-desenvolvimento-de-software-escrever/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/coisas-que-aprendi-com-desenvolvimento-de-software-escrever/</feedburner:origLink></item><item><title>Um dia talvez você precise usar Erlang</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/yYxCGYRYCb4/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Vamos pular a parte hist&amp;oacute;rica desnecess&amp;aacute;ria e ir direto ao ponto. # Ou voc&amp;ecirc; j&amp;aacute; pode ir direto para (&lt;a href="#apresentacao-da-linguagem"&gt;Leitura&lt;/a&gt; ou &lt;a href="#show-me-the-code"&gt;C&amp;oacute;digo&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Erlang&lt;/strong&gt; surgiu para resolver problemas em telecomunica&amp;ccedil;&amp;otilde;es, (antes mesmo de eu nascer), o objetivo era rodar em switches telef&amp;ocirc;nicos, ou seja, atender milh&amp;otilde;es de processos em aparelhos com poder de processamento muito limitado e mesmo assim nunca parar.&lt;/p&gt;
&lt;p&gt;Quem usa Erlang? &amp;ndash; Grandes corpora&amp;ccedil;&amp;otilde;es como: Facebook, Yahoo, GitHub, Amazon, Motorola, CouchDB, RabbitMQ, entre outros.&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o eu acho que isto j&amp;aacute; te diz se ela d&amp;aacute; conta do recado ou n&amp;atilde;o.&lt;/p&gt;
&lt;h2&gt;&lt;a name="apresentacao-da-linguagem"&gt;&lt;/a&gt;Apresenta&amp;ccedil;&amp;atilde;o da linguagem&lt;/h2&gt;
&lt;p&gt;Erlang pode exigir um pouco de dedica&amp;ccedil;&amp;atilde;o e uma certa curva de aprendizado, pois sua sintaxe &amp;eacute; bem diferente do que estamos acostumados a ver em Python, PHP, Java, entre outros. E n&amp;atilde;o &amp;eacute; somente isto, o paradigma de programa&amp;ccedil;&amp;atilde;o tamb&amp;eacute;m muda.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Programa&amp;ccedil;&amp;atilde;o Funcional&lt;/strong&gt;, sim Erlang faz o uso deste paradigma de programa&amp;ccedil;&amp;atilde;o, por&amp;eacute;m &lt;strong&gt;n&amp;atilde;o &amp;eacute; puramente funcional&lt;/strong&gt;, uma vez que o objetivo principal &amp;eacute; trabalhar com programa&amp;ccedil;&amp;atilde;o concorrente e paralela. Atuando fortemente em sistemas como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sistemas distribu&amp;iacute;dos&lt;/strong&gt;, transformar uma aplica&amp;ccedil;&amp;atilde;o que roda sobre um processador em uma aplica&amp;ccedil;&amp;atilde;o distribu&amp;iacute;da entre v&amp;aacute;rios cores e clusters torna-se uma tarefa, relativamente, f&amp;aacute;cil com Erlang.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sistemas em tempo real&lt;/strong&gt;, &lt;strong&gt;sistemas cr&amp;iacute;ticos&lt;/strong&gt; como controle a&amp;eacute;reo ou mesmo uma aplica&amp;ccedil;&amp;atilde;o online que recebe milh&amp;otilde;es de requisi&amp;ccedil;&amp;otilde;es ou milh&amp;otilde;es de dados para serem processados podem manter-se up o tempo todo quando est&amp;aacute; rodando com Erlang.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sistemas tolerantes a falhas&lt;/strong&gt; e que nunca podem parar contam com o &lt;strong&gt;mecanismo de detec&amp;ccedil;&amp;atilde;o de erros&lt;/strong&gt; que permite o controle sobre estes erros em produ&amp;ccedil;&amp;atilde;o, e a possibilidade de fazer o &lt;strong&gt;redeploy da aplica&amp;ccedil;&amp;atilde;o sem parar ou reiniciar o servi&amp;ccedil;o&lt;/strong&gt; permite que sua aplica&amp;ccedil;&amp;atilde;o fique online com o c&amp;oacute;digo antigo e novo ao mesmo tempo e em um certo momento voc&amp;ecirc; s&amp;oacute; "diz" ao servi&amp;ccedil;o para passar a utilizar o novo c&amp;oacute;digo em produ&amp;ccedil;&amp;atilde;o.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;O modelo de concorr&amp;ecirc;ncia &amp;eacute; baseado em processos. Tudo &amp;eacute; bem expl&amp;iacute;cito de modo que voc&amp;ecirc; escolhe o que ser&amp;aacute; processado sequencialmente e o que ser&amp;aacute; processado em paralelo. A &lt;strong&gt;troca de mensagens entre processos &amp;eacute; ass&amp;iacute;ncrona&lt;/strong&gt;, ou seja, enquanto a mensagem &amp;eacute; enviada o processo continua com suas tarefas. E este &amp;eacute; o &amp;uacute;nico m&amp;eacute;todo de troca de informa&amp;ccedil;&amp;atilde;o entre processos, e &amp;eacute; o que torna f&amp;aacute;cil a tarefa de transformar uma aplica&amp;ccedil;&amp;atilde;o comum em uma multicore.&lt;/p&gt;
&lt;h3&gt;E a syntax Erlang?&lt;/h3&gt;
&lt;p&gt;Bem, antes de c&amp;oacute;digo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As vari&amp;aacute;veis s&amp;atilde;o como as constantes que costumamos utilizar, atribu&amp;iacute;mos o valor apenas uma vez e ap&amp;oacute;s isto ele se torna imut&amp;aacute;vel. Torna o debug mais f&amp;aacute;cil e evita diversos outros problemas.&lt;/li&gt;
&lt;li&gt;Os programas s&amp;atilde;o escritos utilizando fun&amp;ccedil;&amp;otilde;es &amp;eacute; bem f&amp;aacute;cil de ler, quando se est&amp;aacute; acostumado com a sintaxe e paradigma utilizados.&lt;/li&gt;
&lt;li&gt;Quando voc&amp;ecirc; cria o arquivo com fun&amp;ccedil;&amp;otilde;es, voc&amp;ecirc; deve dizer explicitamente no in&amp;iacute;cio do arquivo qual o nome do m&amp;oacute;dulo e logo ap&amp;oacute;s quais s&amp;atilde;o as fun&amp;ccedil;&amp;otilde;es deste m&amp;oacute;dulo que ser&amp;atilde;o exportadas para serem utilizadas fora em outros lugares fora do mesmo.&lt;/li&gt;
&lt;li&gt;Erlang possui as diversas estruturas que estamos acostumados utilizar, principalmente para pythonistas, listas, tuplas, dicion&amp;aacute;rios.&lt;/li&gt;
&lt;li&gt;Possui um shell prompt bem legal.&lt;/li&gt;
&lt;li&gt;As particularidades da syntax erlang e estrutura de programa&amp;ccedil;&amp;atilde;o podem ser bem esclarecidas na &lt;a href="http://www.erlang.org/doc/getting_started/seq_prog.html" target="_blank"&gt;documenta&amp;ccedil;&amp;atilde;o&lt;/a&gt;, mas tem um modo bem interativo e legal de aprender o b&amp;aacute;sico, acesse o &lt;a href="http://www.tryerlang.org/" target="_blank"&gt;&lt;strong&gt;Try Erlang&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name="show-me-the-code"&gt;&lt;/a&gt;Hey man! Where is the code?&lt;/h3&gt;
&lt;p&gt;Olhe! &amp;Eacute; um fatorial! (Arquivo &lt;em&gt;&lt;strong&gt;math1.erl&lt;/strong&gt;&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;-module(math1).&lt;br /&gt;-export([fatorial/1]).&lt;br /&gt;&lt;br /&gt;% coment&amp;aacute;rios s&amp;atilde;o feitos assim&lt;br /&gt;% exemplo de fun&amp;ccedil;&amp;atilde;o fazendo o uso de recurs&amp;atilde;o&lt;br /&gt;% fun&amp;ccedil;&amp;atilde;o que calcula o fatorial de um n&amp;uacute;mero&lt;br /&gt;fatorial(0) -&amp;gt; 1;&lt;br /&gt;fatorial(N) when N &amp;gt; 0 -&amp;gt; N*fatorial(N-1).&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Agora vamos ver um exemplo aplicado em um problema do project euler que resolvi com Erlang.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;(&lt;/em&gt;Problema 1&lt;em&gt;) Se n&amp;oacute;s listarmos todos os n&amp;uacute;meros naturais abaixo de 10 que s&amp;atilde;o m&amp;uacute;ltiplos por 3 ou 5, n&amp;oacute;s teremos 3, 5, 6 e 9. A soma desses m&amp;uacute;ltiplos &amp;eacute; 23. Encontre a soma de todos os m&amp;uacute;ltiplos de 3 ou 5 abaixo de 1000.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Arquivo &lt;em&gt;&lt;strong&gt;problema_1.erl&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;-module(problema_1).&lt;br /&gt;-import(lists, [sum/1, seq/1]).&lt;br /&gt;-export([soma_dos_multiplos_de_3_e_5_menores_que_1000/0]).&lt;br /&gt;&lt;br /&gt;soma_dos_multiplos_de_3_e_5_menores_que_1000()-&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;lists:sum([X || X &amp;lt;- lists:seq(1,999), X rem 3 == 0 orelse X rem 5 == 0]).&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Observem que neste eu fa&amp;ccedil;o o uso de &lt;a href="http://www.erlang.org/doc/programming_examples/list_comprehensions.html" target="_blank"&gt;&lt;strong&gt;lists&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;comprehension&lt;/strong&gt;&lt;/a&gt; &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;[X || X &amp;lt;- lists:seq(1,999), X rem 3 == 0 orelse X rem 5 == 0].&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No pr&amp;oacute;ximo exemplo vamos ver o uso do &lt;a href="http://www.erlang.org/doc/reference_manual/patterns.html" target="_blank"&gt;&lt;strong&gt;Pattern Matching&lt;/strong&gt;&lt;/a&gt; que facilita o controle do fluxo do programa, uma vez que n&amp;atilde;o podemos mudar os valores das vari&amp;aacute;veis mais que uma vez, podemos encontrar padr&amp;otilde;es nos valores recebidos por uma fun&amp;ccedil;&amp;atilde;o e definir os comportamentos para cada padr&amp;atilde;o, como no exemplo abaixo, (retirado do Erlang Book, Part 1):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Programa 1.4 define uma fun&amp;ccedil;&amp;atilde;o que converte temperaturas entre as escalas Celsius, Fahrenheit and R'aumur. O primeiro argumento &amp;eacute; uma tupla contendo a escala e o valor da temperatura a ser convertida e o segundo argumento &amp;eacute; a escala que queremos converter o valor passado no primeiro argumento.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Arquivo&lt;em&gt; &lt;/em&gt;&lt;strong&gt;temp_converter&lt;/strong&gt;&lt;em&gt;&lt;strong&gt;.erl&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;-module(temp_converter).&lt;br /&gt;-export([convert/2]).&lt;br /&gt;&lt;br /&gt;convert({fahrenheit, Temp}, celsius) -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {celsius, 5 * (Temp - 32) / 9};&lt;br /&gt;convert({celsius, Temp}, fahrenheit) -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {farenheit, 32 + Temp * 9 / 5};&lt;br /&gt;convert({reaumur, Temp}, celsius) -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {celsius, 10 * Temp / 8};&lt;br /&gt;convert({celsius, Temp}, reaumur) -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {reaumur, 8 * Temp / 10};&lt;br /&gt;convert({X, _}, Y) -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {cannot, convert, X, to, Y}.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Aproveitando este &amp;uacute;ltimo exemplo vamos mostrar como execut&amp;aacute;-lo:&lt;/p&gt;
&lt;p&gt;Vamos partir do princ&amp;iacute;pio que voc&amp;ecirc; tenha o Erlang instalado, entrado na pasta onde est&amp;aacute; o seu m&amp;oacute;dulo &lt;strong&gt;temp_converter&lt;/strong&gt;&lt;em&gt;&lt;strong&gt;.erl &lt;/strong&gt;&lt;/em&gt;e tenha entrado no shell com o comando &lt;strong&gt;erl&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para compilar seu arquivo e ter o m&amp;oacute;dulo dispon&amp;iacute;vel para voc&amp;ecirc; basta fazer:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&amp;gt; c(temp_converter).&lt;br /&gt;{ok,temp_converter}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Agora chame o m&amp;oacute;dulo e fun&amp;ccedil;&amp;atilde;o e execute-o:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;&amp;gt; temp_converter:convert({celsius, 30}, reaumur).&lt;br /&gt;{reaumur,24.0}&lt;br /&gt;&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Os outros exemplos podem ser executados dessa mesma forma.&lt;/p&gt;
&lt;p&gt;Agora deixo para voc&amp;ecirc;s uns links &amp;uacute;teis para encontrarem mais informa&amp;ccedil;&amp;otilde;es e em um pr&amp;oacute;ximo artigo posso mostrar algum exemplo de troca de mensagens entre processos. Espero que tenham gostado!&lt;/p&gt;
&lt;p&gt;Livros: &lt;a href="http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X" target="_blank"&gt;Programming Erlang: Software for a Concurrent World&lt;/a&gt;, &lt;a href="http://www.amazon.com/Erlang-Programming-Francesco-Cesarini/dp/0596518188/ref=pd_sim_b_3" target="_blank"&gt;ERLANG Programming&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Material online: Teste o Erlang online no &lt;a href="http://www.tryerlang.org/" target="_blank"&gt;Try Erlang&lt;/a&gt;, &lt;a href="http://www.erlang.org/" target="_blank"&gt;Erlang.org&lt;/a&gt;, &lt;a href="http://learnyousomeerlang.com/" target="_blank"&gt;Learn you some Erlang&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/um-dia-talvez-voce-precise-usar-erlang/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/um-dia-talvez-voce-precise-usar-erlang/</feedburner:origLink></item><item><title>Meu ambiente de trabalho em 7 itens</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/VpePyVZAhPk/</link><description>&lt;p&gt;H&amp;aacute; muito, muito tempo atr&amp;aacute;s fui &lt;a href="http://andrewsmedina.com/2011/01/27/meu-ambiente-de-trabalho-em-7-itens/" target="_blank"&gt;convidado&lt;/a&gt; a apresentar meu ambiente de trabalho em 7 itens, por Andrews Medina, ent&amp;atilde;o agora vou apresent&amp;aacute;-lo:&lt;/p&gt;
&lt;h2&gt;Ubuntu + VirtualBox&lt;/h2&gt;
&lt;p&gt;Uso, no momento, o &lt;a href="http://www.ubuntu.com/" target="_blank"&gt;Ubuntu&lt;/a&gt; 11.10, meu conhecimento como desenvolvedor pode ser dividido, de uma maneira generalizada, entre antes e depois do Linux. Realmente me trouxe muitos benef&amp;iacute;cios, me for&amp;ccedil;ou a estudar mais, a trabalhar com terminal, me ajudou a resolver os problemas em produ&amp;ccedil;&amp;atilde;o com mais facilidade e rapidez, ao inv&amp;eacute;s de ficar aguardando os meus tickets de suporte serem atendidos, entre outros benef&amp;iacute;cios.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.virtualbox.org/" target="_blank"&gt;VirtualBox&lt;/a&gt;, &amp;eacute; uma m&amp;aacute;quina virtual que posso instalar v&amp;aacute;rios sistemas operacionais, isto &amp;eacute;, para quando preciso fazer testes das aplica&amp;ccedil;&amp;otilde;es web em navegadores que n&amp;atilde;o existem no Ubuntu, &amp;eacute; muito &amp;uacute;til para quem est&amp;aacute; come&amp;ccedil;ando com Linux, pois assim se tiver dificuldades, basta iniciar o sistema operacional antigo que voc&amp;ecirc; utilizava e resolver seu problema.&lt;/p&gt;
&lt;h2&gt;Mozilla Firefox + Google Chrome + Firebug&lt;/h2&gt;
&lt;p&gt;Gosto bastante do &lt;a href="http://br.mozdev.org/download/" target="_blank"&gt;Firefox&lt;/a&gt; e do &lt;a href="https://www.google.com/chrome/" target="_blank"&gt;Chrome&lt;/a&gt;, acho que eles lutam bem mais para proporcionar ao usu&amp;aacute;rio comum e ao desenvolvedor uma maior experi&amp;ecirc;ncia de usu&amp;aacute;rio, implementando novas funcionalidades, incentivando e promovendo a atualiza&amp;ccedil;&amp;atilde;o constante para usufruirmos da nova web que queremos construir em cima dessas atualiza&amp;ccedil;&amp;otilde;es. &amp;nbsp;&lt;/p&gt;
&lt;h2&gt;pip + virtualenv + virtualenvwrapper&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://pip-installer.org/" target="_blank"&gt;pip&lt;/a&gt; &amp;eacute; um gerenciador de pacotes Python. Voc&amp;ecirc; pode instalar, remover, atualizar, buscar pacotes Python com muita facilidade.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://pypi.python.org/pypi/virtualenv" target="_blank"&gt;virtualenv&lt;/a&gt; cria um ambiente isolado, onde voc&amp;ecirc; pode instalar os pacotes Python necess&amp;aacute;rios para sua aplica&amp;ccedil;&amp;atilde;o sem se misturar com os pacotes do sistema, nem com os pacotes de outra aplica&amp;ccedil;&amp;atilde;o. Assim voc&amp;ecirc; pode ativar quando quiser esse ambiente, via terminal, e executar sua aplica&amp;ccedil;&amp;atilde;o com sua vers&amp;atilde;o do Python e pacotes que quiser, deste modo voc&amp;ecirc; mant&amp;eacute;m o controle sobre as depend&amp;ecirc;ncias que sua aplica&amp;ccedil;&amp;atilde;o gera durante o ciclo de desenvolvimento, facilitando o deploy da mesma.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.doughellmann.com/projects/virtualenvwrapper/" target="_blank"&gt;virtualenvwrapper&lt;/a&gt; &amp;eacute; um complemento para o virtualenv que facilita o uso do mesmo, diminuindo o tamanho dos comandos que antes eram digitados para gerenciar estes ambientes virtuais. Por exemplo: ao inv&amp;eacute;s de digitar, no terminal, source ~/.virtualenvs/meu-projeto/bin/activate voc&amp;ecirc; apenas digita, workon meu-projeto, bem legal.&lt;/p&gt;
&lt;h2&gt;Python + Django + Fabric + Apache Mod_wsgi&lt;/h2&gt;
&lt;p&gt;Trabalhei com PHP durante anos, mas agora trabalho com &lt;a href="http://python.org/" target="_blank"&gt;Python&lt;/a&gt; e uso o Framework &lt;a href="https://www.djangoproject.com/" target="_blank"&gt;Django&lt;/a&gt; para desenvolver aplica&amp;ccedil;&amp;otilde;es web, o qual me identifiquei muito tanto pela facilidade de uso, quanto pela robustez, isto sem mencionar que a comunidade &amp;eacute; bem acolhedora e disposta a ajudar. Bem documentado e em constante progresso evolutivo.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://fabfile.org/" target="_blank"&gt;Fabric&lt;/a&gt; &amp;eacute; a app que uso para fazer deploy de aplica&amp;ccedil;&amp;otilde;es Django, aquele lance de fazer um git push para o reposit&amp;oacute;rio git central, depois ir no reposit&amp;oacute;rio da aplica&amp;ccedil;&amp;atilde;o em produ&amp;ccedil;&amp;atilde;o e fazer um git pull, coletar os arquivos est&amp;aacute;ticos e depois reiniciar o servidor para completar o deploy, nunca mais! S&amp;oacute; especifico tudo isso uma vez no arquivo fabfile.py e com apenas um comando eu consigo fazer o deploy de minha aplica&amp;ccedil;&amp;atilde;o o que ajuda muito quem trabalha com deploy cont&amp;iacute;nuo.&lt;/p&gt;
&lt;p&gt;Ainda n&amp;atilde;o trabalhei com ngix, ent&amp;atilde;o at&amp;eacute; hoje fiz o deploy de minhas aplica&amp;ccedil;&amp;otilde;es com Python e Django no servidor web Apache com o m&amp;oacute;dulo &lt;a href="https://code.djangoproject.com/wiki/django_apache_and_mod_wsgi" target="_blank"&gt;Mod_wsgi&lt;/a&gt;, a configura&amp;ccedil;&amp;atilde;o n&amp;atilde;o foi dif&amp;iacute;cil, s&amp;oacute; tive algumas dificuldades em servidores de hospedagens que n&amp;atilde;o t&amp;ecirc;m acesso root, o que restringe um pouco as personaliza&amp;ccedil;&amp;otilde;es, fica tudo muito preso ao que eles querem proteger, mas n&amp;atilde;o tenho o que reclamar quanto ao Apache at&amp;eacute; o momento.&lt;/p&gt;
&lt;h2&gt;Git + Bitbucket + Github&lt;/h2&gt;
&lt;p&gt;N&amp;atilde;o sou, ainda, um ninja &lt;a href="http://git-scm.com/" target="_blank"&gt;Git&lt;/a&gt;, mas uso ele o tempo todo. O desenvolvedor que nunca usou um sistema de controle de vers&amp;otilde;es aprende muito rapidamente com Git, pois &amp;eacute; realmente f&amp;aacute;cil compreender os comandos b&amp;aacute;sicos e fica uma coisa muito linda quando unimos ele ao &lt;a href="https://github.com/" target="_blank"&gt;Github&lt;/a&gt; ou &lt;a href="https://bitbucket.org/" target="_blank"&gt;Bitbucket&lt;/a&gt;, que s&amp;atilde;o servi&amp;ccedil;os que hospedam reposit&amp;oacute;rios Git e ainda fornecem umas funcionalidades visuais para trabalharmos em nossos projetos de divertido e em equipe. Para manter projetos Open Source sem d&amp;uacute;vidas ele &amp;eacute; fabuloso.&lt;/p&gt;
&lt;h2&gt;Sublime Text 2 + Vim&lt;/h2&gt;
&lt;p&gt;Uso, como editor de texto, o &lt;a href="http://www.sublimetext.com/2" target="_blank"&gt;Sublime Text 2,&lt;/a&gt; que no momento &amp;eacute; Beta, mas mesmo assim me proporciona o que quero em um editor, um visual agrad&amp;aacute;vel, super leve, super flex&amp;iacute;vel, se eu quiser escrever plugins &amp;eacute; f&amp;aacute;cil, pois s&amp;atilde;o feitos em Python.&lt;/p&gt;
&lt;p&gt;O &lt;a href="http://www.vim.org/" target="_blank"&gt;Vim&lt;/a&gt; utilizo muito quando estou no servidor via ssh e quero editar alguns scripts ou fazer testes, ou algo parecido, mas n&amp;atilde;o estou usando ele para projetos no momento, somente devido ao fato que ainda n&amp;atilde;o consegui a produtividade com ele, mas isto s&amp;oacute; depende de mim, pois j&amp;aacute; vi outras pessoas usando, e ele &amp;eacute; fabuloso, al&amp;eacute;m de leve e Open Source.&lt;/p&gt;
&lt;h2&gt;Last but not least: M&amp;uacute;sica&lt;/h2&gt;
&lt;p&gt;Dificilmente estou trabalhando sem m&amp;uacute;sica, nem que seja super baixo ou super alto. Enquanto a M&amp;uacute;sica trabalha um lado do c&amp;eacute;rebro o racioc&amp;iacute;nio trabalha o outro.&lt;/p&gt;
&lt;p&gt;Acho que &lt;strong&gt;tudo fica melhor com M&amp;uacute;sica,&lt;/strong&gt; n&amp;atilde;o tenho nem muito o que dizer. =D&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/meu-ambiente-de-trabalho-em-7-itens/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/meu-ambiente-de-trabalho-em-7-itens/</feedburner:origLink></item><item><title>Teste a interface de sua aplicação web no melhor estilo ninja de testes com splinter</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/r0Rm6UPLxlo/</link><description>&lt;h2&gt;&amp;Iacute;ndice&lt;/h2&gt;
&lt;p&gt;Tabela de conte&amp;uacute;dos do artigo:&lt;/p&gt;
&lt;table class="template-table _2-columns"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;td&gt;Conte&amp;uacute;do te&amp;oacute;rico e informa&amp;ccedil;&amp;otilde;es &amp;uacute;teis&lt;/td&gt;
&lt;td&gt;Conte&amp;uacute;do pr&amp;aacute;tico e orienta&amp;ccedil;&amp;otilde;es&lt;/td&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href="#introducao"&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/a&gt; - Interface, qualidade de software&lt;/p&gt;
&lt;p&gt;&lt;a href="#testando-interfaces-web-like-a-ninja-com-splinter"&gt;splinter&lt;/a&gt; - O que &amp;eacute;, quem fez e como funciona&lt;/p&gt;
&lt;p&gt;&lt;a href="#video-palestra-splinter"&gt;V&amp;iacute;deo&lt;/a&gt; - Testes de interface e o splinter&lt;/p&gt;
&lt;p&gt;&lt;a href="#conclusao"&gt;Conclus&amp;atilde;o&lt;/a&gt;; &lt;a href="#agradecimentos-e-creditos"&gt;Agradecimentos e cr&amp;eacute;ditos&lt;/a&gt;;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href="#talk-is-cheap-instalacao-splinter"&gt;Instala&amp;ccedil;&amp;atilde;o do splinter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="#exemplo-splinter-testando-a-busca-do-meu-website"&gt;Exemplo pr&amp;aacute;tico 1&lt;/a&gt; - Testando a busca do meu site&lt;/p&gt;
&lt;p&gt;&lt;a href="#exemplo-splinter-testando-eventos-do-mouse-e-testando-verificando-elementos-na-pagina"&gt;Exemplo pr&amp;aacute;tico 2&lt;/a&gt; - Exemplo ilustrado, eventos do mouse&lt;/p&gt;
&lt;p&gt;&lt;a title="Meu reposit&amp;oacute;rio de exemplos de uso do splinter" href="https://github.com/douglasmiranda/splinter-examples" target="_blank"&gt;Outros exemplos de uso do splinter&lt;/a&gt; - reposit&amp;oacute;rio no github&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tfoot&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;em&gt;i hope you enjoy it!&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tfoot&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name="introducao"&gt;&lt;/a&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Fornecer software de qualidade n&amp;atilde;o se limita em apenas escolher um bom banco de dados, boa estrutura de servidores, arquitetura de sistema bem planejada, linguagens e frameworks que a equipe saiba utiliz&amp;aacute;-los bem. N&amp;atilde;o que isto n&amp;atilde;o leve &amp;agrave; qualidade tamb&amp;eacute;m, mas &amp;eacute; que as "f&amp;aacute;bricas de software" h&amp;aacute; um tempo atr&amp;aacute;s, (algumas at&amp;eacute; hoje), sempre quiseram investir bastante em todos estes quesitos para que n&amp;atilde;o dificultassem a manuten&amp;ccedil;&amp;atilde;o dos softwares e que eles "rodassem" sem problemas.&lt;/p&gt;
&lt;p&gt;E, basicamente, um software de qualidade era isto. Hoje, (na verdade h&amp;aacute; algum tempo, mas a conscientiza&amp;ccedil;&amp;atilde;o ainda est&amp;aacute; em progresso), com a grande concorr&amp;ecirc;ncia e a luta para agradar o usu&amp;aacute;rio, precisamos ser &amp;aacute;geis e certeiros no investimento do tempo de desenvolvimento em rela&amp;ccedil;&amp;atilde;o a principal parte do software, aquela que vai ganhar o usu&amp;aacute;rio, aquela que trar&amp;aacute; o sucesso para quem est&amp;aacute; criando a aplica&amp;ccedil;&amp;atilde;o... A Interface.&lt;/p&gt;
&lt;h2&gt;&lt;a name="testando-interfaces-web-like-a-ninja-com-splinter"&gt;&lt;/a&gt;Testando interfaces web "like a ninja" com &lt;a title="Framework de testes para interface de aplica&amp;ccedil;&amp;otilde;es web" href="http://splinter.cobrateam.info" target="_blank"&gt;splinter&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img class="img_left" src="http://media.douglasmiranda.com/uploads/artigos/128174-124439-master-splinter_super.jpg" alt="Splinter" width="400" height="410" /&gt;Splinter &amp;eacute; um framework de testes para aplica&amp;ccedil;&amp;otilde;es web que tem o objetivo de&amp;nbsp; automatizar o processo de testes executando as a&amp;ccedil;&amp;otilde;es que voc&amp;ecirc; teria de realizar v&amp;aacute;rias vezes manualmente a fim de tornar &amp;aacute;gil, inteligente e sustent&amp;aacute;vel a manuten&amp;ccedil;&amp;atilde;o de interfaces do seu software.&lt;/p&gt;
&lt;p&gt;Ele &amp;eacute; escrito em Python, &amp;eacute; open source e seu desenvolvimento &amp;eacute; liderado pelo grupo de desenvolvimento open source &lt;a title="Web Site Cobrateam" href="http://cobrateam.info/" target="_blank"&gt;Cobrateam&lt;/a&gt;. Mas h&amp;aacute; toda uma comunidade que o mant&amp;eacute;m, e voc&amp;ecirc; tamb&amp;eacute;m pode ajudar no desenvolvimento. :)&amp;nbsp; Mais informa&amp;ccedil;&amp;otilde;es sobre o splinter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://splinter.cobrateam.info/" target="_blank"&gt;Web Site Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title="Documenta&amp;ccedil;&amp;atilde;o do splinter" href="http://splinter.cobrateam.info/docs/"&gt;Documenta&amp;ccedil;&amp;atilde;o&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Grupos de &lt;a title="Grupo de usu&amp;aacute;rios do splinter" href="http://groups.google.com/group/splinter-users"&gt;usu&amp;aacute;rios&lt;/a&gt; e &lt;a title="Grupo de desenvolvedores do splinter" href="http://groups.google.com/group/splinter-developers" target="_blank"&gt;desenvolvedores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title="Reposit&amp;oacute;rio do splinter no github" href="https://github.com/cobrateam/splinter" target="_blank"&gt;Reposit&amp;oacute;rio Oficial&lt;/a&gt; //fa&amp;ccedil;a um fork, improve it e d&amp;ecirc; um pull request =)&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="clearfix"&gt;&lt;a name="video-palestra-splinter"&gt;&lt;/a&gt;O v&amp;iacute;deo a seguir &amp;eacute; uma palestra por &lt;a href="https://twitter.com/andrewsmedina" target="_blank"&gt;Andrews Medina&lt;/a&gt; e &lt;a href="https://twitter.com/franciscosouza" target="_blank"&gt;Francisco Souza&lt;/a&gt; que apresenta o cen&amp;aacute;rio atual das ferramentas de testes de interface, bem como apresenta o splinter.&lt;/p&gt;
&lt;p class="clearfix"&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/29758850?title=0&amp;amp;byline=0&amp;amp;portrait=0" frameborder="0" width="600" height="340"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;h3 class="clearfix"&gt;&lt;a name="talk-is-cheap-instalacao-splinter"&gt;&lt;/a&gt;Talk is cheap...&lt;/h3&gt;
&lt;p&gt;&lt;img class="img_right" src="http://media.douglasmiranda.com/uploads/utils/show-me-the-code-man.jpg" alt="Imagem original em ( http://www.flickr.com/photos/benhusmann/4888266249/ ) &amp;eacute; permitido o uso sob a licen&amp;ccedil;a Creative Common" width="337" height="442" /&gt;&lt;/p&gt;
&lt;p&gt;A seguir alguns pequenos exemplos de uso do splinter, mas voc&amp;ecirc; ter&amp;aacute; de ter instalado ele em tua m&amp;aacute;quina.&lt;/p&gt;
&lt;p&gt;Para os que j&amp;aacute; t&amp;ecirc;m intimidade com Python basta um:&lt;/p&gt;
&lt;p&gt;&lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;$ [sudo] pip install splinter&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; &amp;eacute; iniciante, (melhor que saiba pelo menos o m&amp;iacute;nimo de Python), e quer test&amp;aacute;-lo basta:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Baixar e intalar o Python. &lt;a title="Baixe e instale o Python" href="http://www.python.org/" target="_blank"&gt;python.org&lt;/a&gt; // Se est&amp;aacute; no Mac ou Linux, provavelmente voc&amp;ecirc; j&amp;aacute; o tem instalado. Se tem dificuldades com ingl&amp;ecirc;s siga as instru&amp;ccedil;&amp;otilde;es da &lt;a title="Baixe e instale o Python" href="http://www.python.org/" target="_blank"&gt;Python Brasil&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pip-installer.org/en/latest/installing.html" target="_blank"&gt;Instale o pip&lt;/a&gt;, sem d&amp;uacute;vidas &amp;eacute; a melhor ferramenta para instalar pacoes Python. Busque saber mais sobre ele.&lt;/li&gt;
&lt;li&gt;Ent&amp;atilde;o basta instalar o splinter &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;$ [sudo] pip install splinter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Se a instala&amp;ccedil;&amp;atilde;o n&amp;atilde;o for bem sucedida verifique a sa&amp;iacute;da que apareceu no console, verifique o arquivo de log do pip e copie e cole no Google a mensagem da exce&amp;ccedil;&amp;atilde;o que foi lan&amp;ccedil;ada, voc&amp;ecirc; encontrar&amp;aacute; muitas solu&amp;ccedil;&amp;otilde;es de muitas pessoas que j&amp;aacute; tiveram o mesmo problema. Caso n&amp;atilde;o consiga mesmo entre em contato com a comunidade do pip no Google ou mesmo no GitHub&amp;nbsp; ajudaremos voc&amp;ecirc;. =)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;Para que ele funcione corretamente no Google Chrome siga as &lt;a href="http://splinter.cobrateam.info/docs/drivers/chrome.html" target="_blank"&gt;instru&amp;ccedil;&amp;otilde;es espec&amp;iacute;ficas&lt;/a&gt; de configura&amp;ccedil;&amp;atilde;o para este navegador.&lt;/em&gt;&lt;/p&gt;
&lt;p class="clearfix"&gt;&lt;a name="exemplo-splinter-testando-a-busca-do-meu-website"&gt;&lt;/a&gt;&amp;nbsp;O c&amp;oacute;digo abaixo far&amp;aacute; o seguinte:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;visitar&amp;aacute; meu website&lt;/li&gt;
&lt;li&gt;far&amp;aacute; uma busca com a palavra-chave "python" // aguardar&amp;aacute; o t&amp;eacute;rmino da anima&amp;ccedil;&amp;atilde;o do bot&amp;atilde;o "Pesquisar"&lt;/li&gt;
&lt;li&gt;e verificar&amp;aacute; se h&amp;aacute; resultados para a busca&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="clearfix"&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;A prop&amp;oacute;sito o c&amp;oacute;digo deveria ter somente 15 linhas e tem este tamanho porque eu comentei ele bastante para tentar n&amp;atilde;o deixar d&amp;uacute;vidas.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="clearfix prettyprint"&gt;# -*- coding: utf-8 -*-&lt;br /&gt;import time&lt;br /&gt;from splinter.browser import Browser&lt;br /&gt;# Se eu n&amp;atilde;o passar nenhum driver, Browser(),&lt;br /&gt;# o padr&amp;atilde;o j&amp;aacute; ser&amp;aacute; o firefox.&lt;br /&gt;browser = Browser('firefox')&lt;br /&gt;&lt;br /&gt;url = "http://douglasmiranda.com"&lt;br /&gt;# Na linha abaixo eu visito a url,&lt;br /&gt;# &amp;eacute; neste momento em que o browser se abrir&amp;aacute;&lt;br /&gt;browser.visit(url)&lt;br /&gt;# com o m&amp;eacute;todo fill eu preencho o campo de formul&amp;aacute;rio,&lt;br /&gt;# ele encontra este campo pelo atributo name do input&lt;br /&gt;# para interagir com elementos veja mais formas em:&lt;br /&gt;# http://splinter.cobrateam.info/docs/elements-in-the-page.html&lt;br /&gt;palavra_chave = "python"&lt;br /&gt;browser.fill('q', palavra_chave)&lt;br /&gt;&lt;br /&gt;# estou inserindo este delay aqui porque ao preencher o campo de busca&lt;br /&gt;# h&amp;aacute; uma anima&amp;ccedil;&amp;atilde;o no bot&amp;atilde;o "Pesquisar", este &amp;eacute; o tempo para que&lt;br /&gt;# a anima&amp;ccedil;&amp;atilde;o esteja completa e o bot&amp;atilde;o esteja clic&amp;aacute;vel&lt;br /&gt;# que &amp;eacute; um ponto importante, pois o objeto precisa estar vis&amp;iacute;vel para&lt;br /&gt;# que ele possa ser clicado&lt;br /&gt;time.sleep(0.2)&lt;br /&gt;&lt;br /&gt;# Encontrando o bot&amp;atilde;o de submit do formul&amp;aacute;rio&lt;br /&gt;# que &amp;eacute; um &amp;lt;input type="submit"... dentro de um&lt;br /&gt;# formul&amp;aacute;rio que tem o id="search-form"&lt;br /&gt;# por um seletor CSS, se voc&amp;ecirc; &amp;eacute; familiarizado&lt;br /&gt;# com CSS vai achar bem simples o uso&lt;br /&gt;# mais formas de encontar elementos na p&amp;aacute;gina em:&lt;br /&gt;# http://splinter.cobrateam.info/docs/finding.html&lt;br /&gt;botao_pesquisar = browser.find_by_css("#search-form input[type=submit]")&lt;br /&gt;# Veja que ao encontrar o bot&amp;atilde;o eu posso interagir com ele&lt;br /&gt;# neste caso "estou clicando" nele, que vai submeter meu&lt;br /&gt;# formul&amp;aacute;rio #search-form, enviando a palavra "python" para ser&lt;br /&gt;# pesquisada em meu banco de dados&lt;br /&gt;botao_pesquisar.click()&lt;br /&gt;&lt;br /&gt;# com o m&amp;eacute;todo is_element_present_by_id vou checar se apareceu&lt;br /&gt;# a lista de posts que tem o id="posts-list"&lt;br /&gt;# mais formas checar textos e elementos presentes no corpo da p&amp;aacute;gina em:&lt;br /&gt;# http://splinter.cobrateam.info/docs/matchers.html&lt;br /&gt;if browser.is_element_present_by_id('posts-list'):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "Oh yes! J&amp;aacute; escrevi artigos sobre '%s'! =D" % palavra_chave&lt;br /&gt;else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "N&amp;atilde;o escrevi nenhum artigo sobre '%s'? OMG!" % palavra_chave&lt;br /&gt;&lt;br /&gt;# Ao t&amp;eacute;rmino eu fecho o browser&lt;br /&gt;browser.quit()&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4 class="clearfix"&gt;&lt;a name="exemplo-splinter-testando-eventos-do-mouse-e-testando-verificando-elementos-na-pagina"&gt;&lt;/a&gt;Um exemplo ilustrado&lt;/h4&gt;
&lt;p&gt;Um exemplo cl&amp;aacute;ssico de evento que acontece quando o mouse passa sobre um elemento. Algumas vezes feitos com CSS apenas outras vezes com Javascript. Neste caso &amp;eacute; feito com Javascript e &amp;eacute; poss&amp;iacute;vel v&amp;ecirc;-lo em a&amp;ccedil;&amp;atilde;o nesta p&amp;aacute;gina &lt;a href="/labs/projetos/" target="_blank"&gt;douglasmiranda.com/labs/projetos&lt;/a&gt;. A imagem abaixo ilustra o exemplo:&lt;/p&gt;
&lt;p&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/exemplo-over-out-aparece-desaparece-texto.jpg" alt="Exemplo de efeito mouse over, mouse out com Javascript que n&amp;oacute;s testaremos com splinter" width="600" height="346" /&gt;&lt;/p&gt;
&lt;p class="clearfix"&gt;Porque testar isto? Simples, no decorrer do tempo estou sempre aprimorando o Javascript e CSS do meu site e preciso me certificar que cada altera&amp;ccedil;&amp;atilde;o que eu fizer n&amp;atilde;o ir&amp;aacute; afetar o que j&amp;aacute; estava funcionando, ent&amp;atilde;o assim que eu fa&amp;ccedil;o minhas altera&amp;ccedil;&amp;otilde;es mando rodar os testes e vejo se algum teste teve um resultado inesperado.&lt;/p&gt;
&lt;p class="clearfix"&gt;C&amp;oacute;digo para testar este exemplo:&lt;/p&gt;
&lt;p&gt;&lt;code class="clearfix prettyprint"&gt;# -*- coding: utf-8 -*-&lt;br /&gt;from splinter.browser import Browser&lt;br /&gt;&lt;br /&gt;browser = Browser('chrome')&lt;br /&gt;browser.visit('http://douglasmiranda.com/labs/projetos/')&lt;br /&gt;&lt;br /&gt;li = browser.find_by_css('#ultimos-projetos li').first&lt;br /&gt;&lt;br /&gt;li.mouse_over()&lt;br /&gt;print 'Quando o mouse passa por cima da imagem, (mouseover), a descri&amp;ccedil;&amp;atilde;o aparece? ', li.find_by_css('.descricao').visible&lt;br /&gt;&lt;br /&gt;li.mouse_out()&lt;br /&gt;print '...e quando o mouse est&amp;aacute; fora da imagem, (mouseout), a descri&amp;ccedil;&amp;atilde;o est&amp;aacute; visivel ainda? ', li.find_by_css('.descricao').visible&lt;br /&gt;&lt;br /&gt;browser.quit()&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p class="clearfix"&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;At&amp;eacute; o presente dia, em que estou escrevendo este artigo, 31-12-2011&lt;/em&gt;, &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;mouse_over()&lt;/code&gt; e &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;mouse_out()&lt;/code&gt; n&amp;atilde;o funcionam no firefox.&lt;/p&gt;
&lt;h2 class="clearfix"&gt;&lt;a name="conclusao"&gt;&lt;/a&gt;Finalizando&lt;/h2&gt;
&lt;p class="clearfix"&gt;O splinter, por ser open source e uma ferramenta muito &amp;uacute;til, cresce a cada dia mais, tanto em comunidade, usu&amp;aacute;rios e funcionalidades, at&amp;eacute; o presente momento podemos destacar que ele oferece:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uma API simples, &amp;eacute; realmente muito f&amp;aacute;cil entender o prop&amp;oacute;sito de cada m&amp;eacute;todo.&lt;/li&gt;
&lt;li&gt;Suporte para v&amp;aacute;rios webdrivers (chrome, firefox, zopetestbrowser), sem contar as implementa&amp;ccedil;&amp;otilde;es em andamento.&lt;/li&gt;
&lt;li&gt;Execu&amp;ccedil;&amp;atilde;o de Javascript, bem como a obten&amp;ccedil;&amp;atilde;o de valores retornados pelo Javascript.&lt;/li&gt;
&lt;li&gt;Suporte a ajax, manipula&amp;ccedil;&amp;atilde;o de elementos originados de requisi&amp;ccedil;&amp;otilde;es ass&amp;iacute;ncronas.&lt;/li&gt;
&lt;li&gt;Manipula&amp;ccedil;&amp;atilde;o de cookies.&lt;/li&gt;
&lt;li&gt;E trabalhando para obter uma API completamente documentada e outras coisas que talvez voc&amp;ecirc; tamb&amp;eacute;m possa nos ajudar. =)&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="clearfix"&gt;&lt;a name="agradecimentos-e-creditos"&gt;&lt;/a&gt;Se voc&amp;ecirc; leu at&amp;eacute; aqui, obrigado, d&amp;ecirc; sua opini&amp;atilde;o e talvez voc&amp;ecirc; queira ler outros &lt;a href="/artigo/todos-artigos/"&gt;artigos meus&lt;/a&gt;. :)&lt;/p&gt;
&lt;p class="clearfix"&gt;Estes e outros exemplos est&amp;atilde;o no meu &lt;a title="Reposit&amp;oacute;rio com exemplos de uso do splinter - Framework para testes de interfaces web" href="https://github.com/douglasmiranda/splinter-examples"&gt;reposit&amp;oacute;rio de exemplos de uso do splinter&lt;/a&gt; em meu github.&lt;/p&gt;
&lt;p class="clearfix"&gt;&lt;em&gt;* Imagem usada neste artigo com licen&amp;ccedil;a Creative Common: &lt;a href="http://www.flickr.com/photos/benhusmann/4888266249/" target="_blank"&gt;link para imagem original&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/teste-interface-de-sua-aplicacao-web-no-melhor-estilo-ninja-de-testes-com-splinter/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/teste-interface-de-sua-aplicacao-web-no-melhor-estilo-ninja-de-testes-com-splinter/</feedburner:origLink></item><item><title>Não tenha medo de errar! Feliz 2012!</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/4R45PzkEH8A/</link><description>&lt;h2&gt;Erre mais em 2012&lt;/h2&gt;
&lt;p&gt;&lt;iframe src="http://www.youtube.com/embed/IsSK6aYv9fI" frameborder="0" width="560" height="315"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Acho que com este v&amp;iacute;deo n&amp;atilde;o preciso escrever muito texto, ele diz tudo de uma forma bem bacana.&lt;/p&gt;
&lt;h2&gt;E para na&amp;ccedil;&amp;atilde;o de desenvolvedores, empreendedores e vision&amp;aacute;rios de 2012?&lt;/h2&gt;
&lt;p&gt;Neste pr&amp;oacute;ximo ano vamos tentar n&amp;atilde;o nos prender &amp;agrave;quele emprego que paga nossas contas e aumenta nosso stress. Vamos ousar, tentar, por mais dif&amp;iacute;cil que seja, pois talvez fa&amp;ccedil;a sentido aquela frase que diz que no fim da vida voc&amp;ecirc; se arrepende mais do que deixou de fazer.&lt;/p&gt;
&lt;p&gt;Para os &lt;strong&gt;desenvolvedores&lt;/strong&gt;, participem de projetos que realmente fa&amp;ccedil;am a diferen&amp;ccedil;a, se voc&amp;ecirc; puder saia em busca daquele objetivo que est&amp;aacute; esperando h&amp;aacute; "1 ano" pra ser conquistado.&lt;/p&gt;
&lt;p&gt;Saia da sua cidade, estado ou at&amp;eacute; de seu pa&amp;iacute;s. Se teu alcance ainda n&amp;atilde;o est&amp;aacute; nestas condi&amp;ccedil;&amp;otilde;es, fa&amp;ccedil;a estar ent&amp;atilde;o. Se teu objetivo n&amp;atilde;o &amp;eacute; este, fa&amp;ccedil;a o que quiser s&amp;oacute; n&amp;atilde;o fique parado esperando que algu&amp;eacute;m venha lhe oferecer um emprego melhor, que algu&amp;eacute;m venha lhe ensinar algo novo ou mesmo que seus sonhos simplesmente se realizei sem voc&amp;ecirc; mover um dedo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Empreendedores&lt;/strong&gt; e &lt;strong&gt;Vision&amp;aacute;rios &lt;/strong&gt;com muita "sorte" algu&amp;eacute;m pode ter estes dois dentro de si, em outras ocasi&amp;otilde;es estes s&amp;atilde;o "vendidos separadamente", mas que quando se encontram podem mudar uma realidade, mudar o mundo. Uma breve defini&amp;ccedil;&amp;atilde;o ent&amp;atilde;o destas duas caracter&amp;iacute;sticas:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Vision&amp;aacute;rio&lt;/strong&gt; significa ter vis&amp;otilde;es, ser um sonhador e utopista, muitas vezes com id&amp;eacute;ias mirabolantes e outras com poder para mudar o mundo. &lt;strong&gt;Empreendedor&lt;/strong&gt; &amp;eacute; aquele que possui comportamento arrojado, ativo e proativo, que tem a capacidade de transformar as ideologias dos vision&amp;aacute;rios em neg&amp;oacute;cios. - Cristiano Levone de Oliveira&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ent&amp;atilde;o para vision&amp;aacute;rios e empreendedores s&amp;oacute; resta dizer: "Neste ano, fa&amp;ccedil;a!"&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; planejou, se voc&amp;ecirc; s&amp;oacute; tem a vontade, ou mesmo se quer come&amp;ccedil;ar devagar em um projeto que levar&amp;aacute; anos para ser concretizado, n&amp;atilde;o tenha medo, n&amp;atilde;o desanime e comece j&amp;aacute;. N&amp;atilde;o ache que vai conquistar o mundo da noite para o dia, um simples passo por dia, j&amp;aacute; &amp;eacute; o suficiente para voc&amp;ecirc; "pegar o jeito" e conseguir acelerar esta caminhada sua em dire&amp;ccedil;&amp;atilde;o ao sucesso!&lt;/p&gt;
&lt;p&gt;Por fim, para todos estes, encontrem amigos, parceiros e colaboradores que agreguem &amp;agrave;s suas vidas. Que compartilhem de desejos similares, que colaborem em seus projetos de vida. Ou mesmo pessoas que tenham objetivos n&amp;atilde;o t&amp;atilde;o parecidos, mas que em algum aspecto venha somar com voc&amp;ecirc;.&lt;/p&gt;
&lt;p&gt;Fa&amp;ccedil;am das suas vidas um projeto de sucesso. E &amp;eacute; isto que eu desejo, muito &lt;strong&gt;SUCESSO&lt;/strong&gt; para todos n&amp;oacute;s neste novo ano em que prosseguiremos com os projetos iniciados e daremos in&amp;iacute;cio a novos projetos.&lt;/p&gt;
&lt;p&gt;Feliz Ano Novo!&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/nao-tenha-medo-de-errar/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/nao-tenha-medo-de-errar/</feedburner:origLink></item><item><title>Requests - Módulo para requisições HTTP em Python</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/zeI87PLx1rI/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;H&amp;aacute; momentos em que voc&amp;ecirc; precisa fazer requisi&amp;ccedil;&amp;otilde;es HTTP em um URL seja apenas para obter o conte&amp;uacute;do de apenas uma p&amp;aacute;gina ou mesmo criar um &lt;a title="Defini&amp;ccedil;&amp;atilde;o de Web Crawler na Wikip&amp;eacute;dia" href="http://pt.wikipedia.org/wiki/Web_crawler" target="_blank"&gt;web crawler&lt;/a&gt; para varrer a web em busca de par&amp;acirc;metros que eu especificar para obter o que quero. Essas requisi&amp;ccedil;&amp;otilde;es tamb&amp;eacute;m podem fazer mais que recuperar dados, podem enviar informa&amp;ccedil;&amp;otilde;es via HTTP para que sejam processadas, gravadas e/ou retornadas.&lt;/p&gt;
&lt;p&gt;O protocolo HTTP oferece muito, na verdade muito mais do que utilizamos atualmente, podemos ver o seu uso extensivo ao utilizar &lt;a title="Defini&amp;ccedil;&amp;atilde;o de REST na Wikip&amp;eacute;dia" href="http://pt.wikipedia.org/wiki/REST" target="_blank"&gt;REST&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mas o foco deste artigo n&amp;atilde;o &amp;eacute; adentrar a fundo nestas defini&amp;ccedil;&amp;otilde;es e como utiliz&amp;aacute;-las, mas sim apresentar o Requests que tem o simples objetivo de fornecer ao desenvolvedor Python uma maneira simples e elegante de fazer requisi&amp;ccedil;&amp;otilde;es HTTP, claro que temos diversos m&amp;oacute;dulos para trabalhar com isto, como o urllib e httplib e ainda temos as vers&amp;otilde;es destes m&amp;oacute;dulos urllib2, urllib3 e httplib2. Com Requests, creio que voc&amp;ecirc; n&amp;atilde;o precisar&amp;aacute; se preocupar em utilizar todas elas no meio de teu c&amp;oacute;digo, tornando mais limpo e simples o ato de fazer requisi&amp;ccedil;&amp;otilde;es, mas vamos logo ao que interessa!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Requests is an elegant and simple HTTP library for Python, built for human beings.&lt;br /&gt; -- &lt;a href="http://kennethreitz.com/pages/open-projects.html"&gt;Kenneth Reitz&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;O lance de dizer que ele &amp;eacute; constru&amp;iacute;do para seres humanos &amp;eacute; por causa da sua simplicidade e facilidade de uso que deixa tudo mais &amp;oacute;bvio e um c&amp;oacute;digo mais limpo.&lt;/p&gt;
&lt;h2&gt;Como funciona e onde posso saber mais sobre o Requests?&lt;/h2&gt;
&lt;p&gt;Se j&amp;aacute; compreendeu do que se trata o Requests basta instalar, &lt;a title="Documenta&amp;ccedil;&amp;atilde;o do Requests" href="http://docs.python-requests.org/en/latest/" target="_blank"&gt;acessar sua documenta&amp;ccedil;&amp;atilde;o&lt;/a&gt;, and have fun :)&lt;/p&gt;
&lt;p&gt;Instale-o com &lt;a title="Instalador de pacotes Python " href="http://www.pip-installer.org/en/latest/index.html" target="_blank"&gt;pip&lt;/a&gt; &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;$ pip install requests&lt;/code&gt;. &lt;a title="Mais detalhes sobre a instala&amp;ccedil;&amp;atilde;o do Requests" href="http://docs.python-requests.org/en/latest/user/install/#install" target="_blank"&gt;Mais detalhes aqui&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Requisi&amp;ccedil;&amp;atilde;o GET&lt;/h3&gt;
&lt;p&gt;Vou acessar minha timeline do twitter pelo servi&amp;ccedil;o que o mesmo oferece um retorno em &lt;a title="Defini&amp;ccedil;&amp;atilde;o de JSON na Wikip&amp;eacute;dia" href="http://pt.wikipedia.org/wiki/JSON" target="_blank"&gt;JSON&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;import requests&lt;br /&gt;&lt;br /&gt;r = requests.get('https://twitter.com/statuses/user_timeline/douglaswebdev.json')&lt;br /&gt;print data&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Requisi&amp;ccedil;&amp;atilde;o POST&lt;/h3&gt;
&lt;p&gt;N&amp;atilde;o fiz nenhum exemplo meu pra demonstar o post, mas existe o URL original que d&amp;aacute; pra gente exemplificar.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;import requests&lt;br /&gt;&lt;br /&gt;dados = {'nome': 'Douglas Miranda', 'website': 'http://douglasmiranda.com'}&lt;br /&gt;r = requests.post("http://httpbin.org/post", data=dados)&lt;br /&gt;print r.content&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No retorno voc&amp;ecirc; vera que o dicion&amp;aacute;rio de dados chamado &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;dados&lt;/code&gt; foi enviado com sucesso, algo deste tipo:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;{&lt;br /&gt;&amp;nbsp; "origin": "177.39.128.245", &lt;br /&gt;&amp;nbsp; "files": {}, &lt;br /&gt;&amp;nbsp; "form": {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "website": "http://douglasmiranda.com", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "nome": "Douglas Miranda"&lt;br /&gt;&amp;nbsp; }, &lt;br /&gt;&amp;nbsp; "headers": {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Content-Length": "60", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Accept-Encoding": "identity, deflate, compress, gzip", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "X-Forwarded-Port": "80", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Host": "httpbin.org", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Accept": "*/*", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "User-Agent": "python-requests/0.8.7", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Connection": "keep-alive", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Content-Type": "application/x-www-form-urlencoded"&lt;br /&gt;&amp;nbsp; }, &lt;br /&gt;&amp;nbsp; "url": "http://httpbin.org/post", &lt;br /&gt;&amp;nbsp; "args": {}, &lt;br /&gt;&amp;nbsp; "data": ""&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Estes exemplos s&amp;atilde;o o mais &amp;oacute;bvio que ele deveria fazer, h&amp;aacute; muito mais, como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multipart File Uploads&lt;/li&gt;
&lt;li&gt;Manipula&amp;ccedil;&amp;atilde;o de Cookies e Sess&amp;otilde;es&lt;/li&gt;
&lt;li&gt;Autentica&amp;ccedil;&amp;atilde;o&lt;/li&gt;
&lt;li&gt;entre outros&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voc&amp;ecirc; pode ainda enviar requisi&amp;ccedil;&amp;otilde;es HEAD, GET, POST, PUT, PATCH, e DELETE.&lt;/p&gt;
&lt;h3&gt;Autentica&amp;ccedil;&amp;atilde;o&lt;/h3&gt;
&lt;p&gt;&amp;Eacute; algo muito simples, como:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;import requests&lt;br /&gt;&lt;br /&gt;requests.get('https://api.github.com/user', auth=('user', 'pass'))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Mais sobre esta e outras formas de autentica&amp;ccedil;&amp;atilde;o voc&amp;ecirc; pode ver &lt;a title="Basic, Digest and OAuth Authentication" href="http://docs.python-requests.org/en/latest/user/quickstart/#basic-authentication" target="_blank"&gt;nesta sess&amp;atilde;o&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;E por fim...&lt;/h2&gt;
&lt;p&gt;Por fim acesse &lt;a href="http://python-requests.org" target="_blank"&gt;python-requests.org&lt;/a&gt; e voc&amp;ecirc; ver&amp;aacute; que h&amp;aacute; outras &lt;a href="http://docs.python-requests.org/en/latest/user/advanced/" target="_blank"&gt;funcionalidades avan&amp;ccedil;adas&lt;/a&gt; bem legais como &lt;strong&gt;requisi&amp;ccedil;&amp;atilde;o assincrona&lt;/strong&gt;, &lt;strong&gt;hooks&lt;/strong&gt;, entre outras personaliza&amp;ccedil;&amp;otilde;es bem legais que voc&amp;ecirc; pode fazer. Descubra mais e compartilhe conosco. =)&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/requests-modulo-para-requisicoes-http-em-python/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/requests-modulo-para-requisicoes-http-em-python/</feedburner:origLink></item><item><title>Exibindo um ManyToManyField como checkboxes no Django Admin</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/NnRT2vqh0uo/</link><description>&lt;h2&gt;Problema&lt;/h2&gt;
&lt;p&gt;Vamos supor que, neste caso, voc&amp;ecirc; queira fazer uma app blog, que utilizar&amp;aacute; o modelo de postagem parecido com o do Wordpress, onde &amp;eacute; poss&amp;iacute;vel atribuir a mesma postagem v&amp;aacute;rias categorias, para tal utilizaremos um relacionamento &lt;a href="#"&gt;ManyToMany&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Analisando os models abaixo, considere como parte do &lt;em&gt;&lt;strong&gt;models.py&lt;/strong&gt;&lt;/em&gt; da sua app blog:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;from django.db import models&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Categoria(models.Model):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; categoria = models.CharField('categoria', max_length=60)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ... outros campos&lt;br /&gt;&lt;br /&gt;class Artigo(models.Model):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ..outros campos&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; categorias = models.ManyToManyField(Categoria)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ..outros campos&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Levando em conta o modelo acima, se apenas registrarmos os models, no &lt;em&gt;&lt;strong&gt;admin.py,&lt;/strong&gt;&lt;/em&gt; para eles ficarem dispon&amp;iacute;veis no painel de administra&amp;ccedil;&amp;atilde;o, desta forma:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;from django.contrib import admin&lt;br /&gt;from models import Artigo, Categoria&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;admin.site.register(Artigo)&lt;br /&gt;admin.site.register(Categoria)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Teremos um resultado assim, no campo categorias:&lt;strong&gt; &lt;br /&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/imagens/selectbox-categorias.png" alt="select" width="158" height="175" /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class="clearfix"&gt;Solu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Agora para obtermos o que queremos, que &amp;eacute; a possibilidade de selecionar as categorias com checkboxes, devemos fazer da seguinte forma nosso &lt;em&gt;&lt;strong&gt;admin.py&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint"&gt;from django.db import models&lt;br /&gt;from django.contrib import admin&lt;br /&gt;from models import Artigo, Categoria&lt;br /&gt;from django.forms import CheckboxSelectMultiple&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class ArtigoAdmin(admin.ModelAdmin):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; formfield_overrides = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; models.ManyToManyField: {'widget': CheckboxSelectMultiple},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;admin.site.register(Artigo, ArtigoAdmin)&lt;br /&gt;admin.site.register(Categoria)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Com isto obteremos o seguinte resultado: &lt;strong&gt;&lt;br /&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/imagens/checkboxes.png" alt="checkbox" width="120" height="132" /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Por&amp;eacute;m, (sempre h&amp;aacute; um por&amp;eacute;m), esta n&amp;atilde;o &amp;eacute; a forma mais bonita, organizada e talvez at&amp;eacute; n&amp;atilde;o muito pythonica de se fazer, mas sou suspeito, sou bem iniciante em tudo isto. :)&lt;/p&gt;
&lt;p&gt;Talvez em um outro artigo eu fale melhor sobre esta organiza&amp;ccedil;&amp;atilde;o de c&amp;oacute;digo em sua app, mas n&amp;atilde;o &amp;eacute; nada muito dif&amp;iacute;cil, o lance &amp;eacute; que j&amp;aacute; temos por conven&amp;ccedil;&amp;atilde;o que colocar estas personaliza&amp;ccedil;&amp;otilde;es de formul&amp;aacute;rios em um arquivo &lt;em&gt;&lt;strong&gt;forms.py&lt;/strong&gt;&lt;/em&gt; dentro de minha app. Mas da forma que apresentei, funciona, resolve o problema e para um campo s&amp;oacute;, at&amp;eacute; que n&amp;atilde;o fica ruim, se vamos personalizar muitos campos do formul&amp;aacute;rio, ent&amp;atilde;o &amp;eacute; altamente recomend&amp;aacute;vel, trabalhar de forma mais organizada.&lt;/p&gt;
&lt;p&gt;Se eu errei, n&amp;atilde;o me chame de tolo em pensamento, fale a&amp;iacute; nos coment&amp;aacute;rios para que eu possa corrigir. :)&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/exibindo-um-manytomanyfield-como-checkboxes-no-django-admin/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/exibindo-um-manytomanyfield-como-checkboxes-no-django-admin/</feedburner:origLink></item><item><title>Aprendendo Python e Django</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/2IHr3WSkuPk/</link><description>&lt;h2&gt;Come&amp;ccedil;ando...&lt;/h2&gt;
&lt;p&gt;&lt;img class="img_left" style="border-width: initial !important; border-color: initial !important;" src="http://media.douglasmiranda.com/uploads/artigos/python-e-django.jpg" alt="Python e Django" width="274" height="282" /&gt;Vou compartilhar a forma que utilizei nesses &amp;uacute;ltimos meses pra aprender novas ferramentas e tecnologias que est&amp;atilde;o me ajudando e me tornando um profissional mais valorizado e mais feliz! :)&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="color: #666666; background-color: #ffffff;"&gt;&lt;a href="#materiais-python"&gt;Materiais - Python&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="color: #666666; background-color: #ffffff;"&gt;&lt;a href="#materiais-django"&gt;Materiais -&amp;nbsp;Django&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="color: #666666; background-color: #ffffff;"&gt;&lt;a href="#pergunte"&gt;Pergunte!&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="color: #666666; background-color: #ffffff;"&gt;&lt;a href="#seja-um-cientista"&gt;Seja um cientista&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="color: #666666; background-color: #ffffff;"&gt;&lt;a href="#finalizando"&gt;Finalizando&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="clearfix"&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;a name="materiais-python"&gt;&lt;/a&gt;Materiais - Python&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Livro: &lt;a class="external" title="Link para o livro" href="http://greenteapress.com/thinkpython/thinkpython.html" target="_blank"&gt;Think Python&lt;/a&gt; # Confesso que n&amp;atilde;o fiz tudo, mas fiz uma grande parte, li, e entendi o b&amp;aacute;sico do Python, foi bem esclarecedor.&lt;/li&gt;
&lt;li&gt;&lt;a class="external" href="http://docs.python.org/tutorial/" target="_blank"&gt;Python Tutorial&lt;/a&gt; # Se voc&amp;ecirc; ler tudo vai ser muito bom, agora se n&amp;atilde;o der, v&amp;aacute; aprendendo e volte sempre, veja algum t&amp;oacute;pico, sempre h&amp;aacute; algo que voc&amp;ecirc; acaba entendendo melhor.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.python.org/" target="_blank"&gt;Documenta&amp;ccedil;&amp;atilde;o do Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;E treine da forma como desejar, no meu caso fui resolvendo problemas do Projeto Euler, vi tutoriais e fiz, fiz pequenos programas que j&amp;aacute; tinha feito em outra linguagem.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name="materiais-django"&gt;&lt;/a&gt;Materiais - Django&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/1.3/intro/tutorial01/" target="_blank"&gt;Tutorial Django&lt;/a&gt;&amp;nbsp;# Voc&amp;ecirc; vai aprender fazer um sistema de enquete simples, por&amp;eacute;m o tutorial contempla uma grande parte do que voc&amp;ecirc; precisa saber para come&amp;ccedil;ar a trabalhar com Django.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com" target="_blank"&gt;Documenta&amp;ccedil;&amp;atilde;o do Django&lt;/a&gt; # A documenta&amp;ccedil;&amp;atilde;o &amp;eacute; excelente, vai encontrar o que precisa l&amp;aacute;, com certeza!&lt;/li&gt;
&lt;li&gt;E como outras fontes de pesquisa tamb&amp;eacute;m usei o &lt;a href="http://www.djangobook.com/" target="_blank"&gt;The Django Book&lt;/a&gt;&amp;nbsp;e o &lt;a href="http://www.aprendendodjango.com/" target="_blank"&gt;Aprendendo Django no Planeta Terra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;E quando voc&amp;ecirc; j&amp;aacute; est&amp;aacute; fazendo algo e precisa de outras solu&amp;ccedil;&amp;otilde;es existe sempre o &lt;a href="http://djangosnippets.org/" target="_blank"&gt;Django Snippets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;O Google &amp;eacute; um grande aliado tamb&amp;eacute;m, sempre tr&amp;aacute;s nos resultados f&amp;oacute;runs, grupos de discuss&amp;atilde;o, entre outros com pessoas com a mesma d&amp;uacute;vida que voc&amp;ecirc; e a comunidade sempre responde. :)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name="pergunte"&gt;&lt;/a&gt;Pergunte!&lt;/h3&gt;
&lt;p&gt;D&amp;uacute;vidas s&amp;oacute; existem para serem esclarecidas, ent&amp;atilde;o pergunte ao seus amigos, contatos, followers, membros da comunidade em geral. Se houver algu&amp;eacute;m que voc&amp;ecirc; conhe&amp;ccedil;a que possa tirar suas d&amp;uacute;vidas melhor.&lt;/p&gt;
&lt;h3&gt;&lt;a name="seja-um-cientista"&gt;&lt;/a&gt;Seja um cientista&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Quem nunca errou nunca experimentou nada novo.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ALBERT EINSTEIN&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Procure experimentar, questione, fuja da regra. Junte tudo o que h&amp;aacute; de bom e forme o seu jeito de aprender, desenvolver, pensar e compartilhe. Esse tipo de conhecimento faz muito mais sentido quando voc&amp;ecirc; divide com todos. =)&lt;/p&gt;
&lt;h2&gt;&lt;a name="finalizando"&gt;&lt;/a&gt;Finalizando&lt;/h2&gt;
&lt;p&gt;Bem, n&amp;atilde;o h&amp;aacute; nada para finalizar, como disse, estou &lt;strong&gt;aprendendo,&lt;/strong&gt;&amp;nbsp;ent&amp;atilde;o haver&amp;atilde;o muitos outros artigos sobre coisas que vou aprendendo com o passar do tempo e vou compartilhar com voc&amp;ecirc;s aqui ou em qualquer lugar desta vasta web, deste vasto mundo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Quem quiser come&amp;ccedil;ar e achar que o que listei s&amp;atilde;o poucas op&amp;ccedil;&amp;otilde;es, para python, ent&amp;atilde;o de uma olhada &lt;a class="external" href="http://www.python.org.br/wiki/DocumentacaoPython" target="_blank"&gt;nesta p&amp;aacute;gina&lt;/a&gt; e veja se tem algo que lhe ajude. :)&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/aprendendo-python-e-django/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/aprendendo-python-e-django/</feedburner:origLink></item><item><title>Coisas que aprendi com desenvolvimento de software: Leitura</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/uBg0Lj86fIM/</link><description>&lt;h2&gt;Introdu&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;Quero fazer, uma s&amp;eacute;rie de artigos pra guardar para mim, e ao mesmo tempo compartilhar com todos os pontos que acho importante analisar quando falamos de &lt;strong&gt;desenvolvimento de software&lt;/strong&gt;. Ent&amp;atilde;o de tempos em tempos abordarei um tema espec&amp;iacute;fico em cada artigo.&lt;/p&gt;
&lt;p&gt;Vamos come&amp;ccedil;ar com o tema que &amp;eacute; simplesmente uma palavra que nos acompanha desde os tempos de escola, tempos em que os professores pediam para que n&amp;oacute;s l&amp;ecirc;ssemos, como se ler fosse a chave para tudo nessa vida. Se &amp;eacute; para tudo n&amp;atilde;o sei, mas para muitas coisas coisas, realmente, pode acreditar que &amp;eacute;!&lt;/p&gt;
&lt;h2&gt;Use a leitura para entender certo ou errado, para concordar ou confrontar&lt;/h2&gt;
&lt;p&gt;O erro sempre lhe acompanhar&amp;aacute;, desculpe se estou sendo dram&amp;aacute;tico, mas &amp;eacute; a pura verdade! N&amp;atilde;o deixe se levar pelo fato de que voc&amp;ecirc; leu dezenas de livros este ano e outra pessoa n&amp;atilde;o leu um que voc&amp;ecirc; &amp;eacute; um ser superior.&lt;/p&gt;
&lt;p&gt;Use a leitura para para reunir as informa&amp;ccedil;&amp;otilde;es que voc&amp;ecirc; precisa para descutir sobre o assunto com outra pessoa, &lt;strong&gt;n&amp;atilde;o tenha medo de estar errado&lt;/strong&gt;, voc&amp;ecirc; pode interpretar errado a qualquer momento, s&amp;oacute; o que n&amp;atilde;o pode fazer &amp;eacute; ficar com a d&amp;uacute;vida ou pensar que compreendeu a origem do universo lendo apenas o primeiro par&amp;aacute;grafo do livro da vida.&lt;/p&gt;
&lt;p&gt;Leia sobre algum artigo, que seja de interesse seu e de sua classe talvez, interrompa o professor que voc&amp;ecirc; acha que pode saber sobre o tema e &lt;strong&gt;proponha uma discuss&amp;atilde;o,&lt;/strong&gt; ou apenas &lt;strong&gt;fa&amp;ccedil;a questionamentos&lt;/strong&gt;, talvez ele possa te responder, e se n&amp;atilde;o concordar, &lt;strong&gt;exponha teu ponto de vista&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Na pior das hip&amp;oacute;teses se voc&amp;ecirc; estiver confrontando e ainda estiver errado, voc&amp;ecirc; n&amp;atilde;o far&amp;aacute; isto novamente.&lt;/p&gt;
&lt;h2&gt;Leitura e programa&amp;ccedil;&amp;atilde;o&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;H&amp;aacute; muitas v&amp;iacute;deo aulas, palestras dispon&amp;iacute;veis em canais de v&amp;iacute;deo, podcasts e diversas outras m&amp;iacute;dias com conte&amp;uacute;do sobre programa&amp;ccedil;&amp;atilde;o e tudo mais. Mas as fontes ricas em conte&amp;uacute;do que s&amp;atilde;o documenta&amp;ccedil;&amp;otilde;es, livros, artigos, posts, revistas, entre outros est&amp;atilde;o no formato de texto, (&lt;em&gt;eu sei, voc&amp;ecirc; &amp;eacute; programador e &amp;eacute; uma tarefa simples fazer o computador ler o texto para voc&amp;ecirc;, mas n&amp;atilde;o vamos disutir isto agora, ok?&lt;/em&gt;), e &lt;strong&gt;voc&amp;ecirc; sempre descobre algo novo&lt;/strong&gt; sobre sua ferramenta, plataforma, linguagem e vai acabar se acostumando a ler.&lt;/p&gt;
&lt;p&gt;Se voc&amp;ecirc; &amp;eacute; programador e n&amp;atilde;o se convenceu muito com o par&amp;aacute;grafo de cima voc&amp;ecirc; vai concordar com o pr&amp;oacute;ximo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voc&amp;ecirc; passa a maior parte do seu tempo de programador lendo c&amp;oacute;digos&lt;/strong&gt; e n&amp;atilde;o escrevendo, n&amp;atilde;o sou eu que estou dizendo isto &amp;eacute; resultado de pesquisas. Voc&amp;ecirc; deve ler muito mais, e talvez melhor que muitas pessoas, pois voc&amp;ecirc; escrever&amp;aacute; um programa em uma linguagem de programa&amp;ccedil;&amp;atilde;o, que se voc&amp;ecirc; prestar aten&amp;ccedil;&amp;atilde;o, praticamente est&amp;aacute; lendo e escrevendo em outro idioma, e voc&amp;ecirc; n&amp;atilde;o est&amp;aacute; escrevendo para somente si mesmo, ser&amp;aacute; para outras pessoas que possam vir a trabalhar em seu c&amp;oacute;digo e est&amp;aacute; escrevendo para o usu&amp;aacute;rio final tamb&amp;eacute;m, n&amp;atilde;o importa se o programa que voc&amp;ecirc; est&amp;aacute; escrevendo &amp;eacute; de exibi&amp;ccedil;&amp;atilde;o de imagens e n&amp;atilde;o haver&amp;aacute; texto, (&lt;em&gt;acho que voc&amp;ecirc; me entendeu&lt;/em&gt;), e como ler aprimora a escrita e escrever aprimora a leitura, voc&amp;ecirc; far&amp;aacute; os dois muito bem se possuir dedica&amp;ccedil;&amp;atilde;o.&lt;/p&gt;
&lt;p&gt;Desenvolvimento de software requer que voc&amp;ecirc; mantenha-se atualizado, livros atualizados, artigos, revistas, mas se quiser algo mais curto, talvez uma organizada nos seus feeds ajude voc&amp;ecirc; manter foco nos blogs que tem melhor conte&amp;uacute;do para voc&amp;ecirc; manter a rotina de leitura atualizada.&lt;/p&gt;
&lt;p&gt;N&amp;atilde;o sou um super leitor que j&amp;aacute; leu todos livros de desenvolvimento e uma cole&amp;ccedil;&amp;atilde;o inteira do meu autor favorito, levou um tempo at&amp;eacute; que eu notasse o verdadeiro valor da leitura, hoje reconhe&amp;ccedil;o a import&amp;acirc;ncia. Ent&amp;atilde;o com 10, 20 ou 50 anos nunca &amp;eacute; tarde para come&amp;ccedil;ar algo novo, quem sabe voc&amp;ecirc; deva come&amp;ccedil;ar lendo uma revista de carros ou esportes talvez, mas vai l&amp;aacute;, tente! =)&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/coisas-que-aprendi-com-desenvolvimento-de-software-leitura/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/coisas-que-aprendi-com-desenvolvimento-de-software-leitura/</feedburner:origLink></item><item><title>Dicas para se tornar um ótimo profissional</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/aeaGDRCpPpA/</link><description>&lt;p&gt;Ultimamente tenho expandido minhas sess&amp;otilde;es de leitura, abrindo espa&amp;ccedil;o para artigos que venham complementar o profissional que quero me tornar, ou seja, um especialista na minha &amp;aacute;rea, mas que compreende todo o processo de desenvolvimento de um produto, trabalho em equipe e como se tornar um empreendedor de sucesso.&lt;/p&gt;
&lt;p&gt;Mesmo nesse tipo de leitura encontramos dicas fundamentais para qualquer &amp;aacute;rea, mesmo para nossa &amp;aacute;rea de desenvolvimento de software que pensamos que &amp;eacute; muito diferente de todas outras, por&amp;eacute;m alguns fundamentos b&amp;aacute;sicos s&amp;atilde;o bem parecidos, ent&amp;atilde;o indico para leitura o artigo "&lt;a title="Artigo do blog &amp;quot;Insistimento&amp;quot;" href="http://www.insistimento.com.br/2011/04/07/10-bons-conselhos-para-ser-um-excelente-profissional/" target="_blank"&gt;10 bons conselhos para ser um excelente profissional&lt;/a&gt;", ele descreve cada item da lista abaixo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Estude!&lt;/li&gt;
&lt;li&gt;Conhe&amp;ccedil;a pessoas e fa&amp;ccedil;a ser conhecido.&lt;/li&gt;
&lt;li&gt;Fa&amp;ccedil;a bem feito o seu trabalho, mas saiba tamb&amp;eacute;m, fazer o trabalho do colega.&lt;/li&gt;
&lt;li&gt;Cuidado para n&amp;atilde;o ir com muita sede ao pote.&lt;/li&gt;
&lt;li&gt;Trabalhe com alegria e entusiasmo.&lt;/li&gt;
&lt;li&gt;Afaste-se de pessoas negativas.&lt;/li&gt;
&lt;li&gt;Fa&amp;ccedil;a mais com menos.&lt;/li&gt;
&lt;li&gt;Fa&amp;ccedil;a o poss&amp;iacute;vel e o imposs&amp;iacute;vel para ajudar.&lt;/li&gt;
&lt;li&gt;Voc&amp;ecirc; atrai aquilo que voc&amp;ecirc; pensa.&lt;/li&gt;
&lt;li&gt;Declare seu amor pelo trabalho que faz.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Para quem quer expandir suas leituras para o universo empreendedor tamb&amp;eacute;m o blog "&lt;a title="Blog de empreendedorismo" href="http://www.saiadolugar.com.br/" target="_blank"&gt;Saia do Lugar&lt;/a&gt;" &amp;eacute; uma &amp;oacute;tima fonte, eles escrevem de uma forma objetiva e bem simples.&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/dicas-para-se-tornar-um-otimo-profissional/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/dicas-para-se-tornar-um-otimo-profissional/</feedburner:origLink></item><item><title>Meu primeiro pequeno projeto desenvolvido utilizando Django.</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/rgbx5xJuM1w/</link><description>&lt;p&gt;&lt;a class="external" title="Django official website" href="https://www.djangoproject.com/" target="_blank"&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/django-logo-negative_large.png" alt="Django" width="680" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;django-admin.py startproject douglasmiranda&lt;/code&gt; primeiro comando que possibilitou que eu estivesse escrevendo neste meu blog hoje.&lt;/p&gt;
&lt;p&gt;Depois veio um &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;./manage.py startapp blog&lt;/code&gt;, e mais tarde, finalmente, um &lt;code class="code-inline" style="display: inline-block; background-color: #f8f8ff; border: 1px solid #dedede; color: #444444; font-size: 12px; padding: 0pt 0.2em; border-radius: 3px 3px 3px 3px;"&gt;git push origin master&lt;/code&gt; e l&amp;aacute; estava eu, (ou estou eu aqui), que seja, &amp;agrave;s vezes me perco no espa&amp;ccedil;o e tempo quando escrevo. #fringefellings&lt;/p&gt;
&lt;h2&gt;Primeiras impress&amp;otilde;es&lt;/h2&gt;
&lt;p&gt;Logo no in&amp;iacute;cio, imaginei que demoraria bastante tempo para conseguir fazer algo simples em Django, pois mal faziam 3 meses que tinha come&amp;ccedil;ado aprender Python e aprendendo a usar o Git, dentre as outras coisas que tenho de fazer durante o dia/noite. Mas assim que li um pouco e fiz o tutorial dispon&amp;iacute;vel no site do Django, me senti mais familiarizado com o framework.&lt;/p&gt;
&lt;p&gt;Comunidade acolhedora, em crescimento no Brasil, &lt;a class="external" title="Documenta&amp;ccedil;&amp;atilde;o do Django" href="https://docs.djangoproject.com/" target="_blank"&gt;documenta&amp;ccedil;&amp;atilde;o&lt;/a&gt; excelente e iniciativas legais como o &lt;a class="external" href="http://www.aprendendodjango.com/" target="_blank"&gt;&lt;strong&gt;Aprendendo Django no Planeta Terra&lt;/strong&gt;&lt;/a&gt;, &lt;a class="external" href="http://www.djangobook.com/" target="_blank"&gt;&lt;strong&gt;The Django Book&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Caracter&amp;iacute;sticas que apreciei:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flex&amp;iacute;vel&lt;/li&gt;
&lt;li&gt;Extens&amp;iacute;vel&lt;/li&gt;
&lt;li&gt;F&amp;aacute;cil entendimento&lt;/li&gt;
&lt;li&gt;Margem de aprendizagem, relativamente, curta. Se voc&amp;ecirc; quer fazer coisas simples, rapidamente voc&amp;ecirc; estar&amp;aacute; apto, se quiser complicar, &amp;eacute; s&amp;oacute; estudar mais um pouquinho que as coisas v&amp;atilde;o se resolvendo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ainda n&amp;atilde;o me deparei com contras que impossibilitaram o uso para mim, mas li que algumas coisas precisam ser aprimoradas, como a utiliza&amp;ccedil;&amp;atilde;o de Django com banco de dados NoSQL e alguns outros pontos que ainda acho que n&amp;atilde;o estou apto a discutir, por&amp;eacute;m vejo que para os problemas h&amp;aacute; solu&amp;ccedil;&amp;otilde;es, mesmo que n&amp;atilde;o-oficiais e/ou de terceiros.&lt;/p&gt;
&lt;h2&gt;E agora?&lt;/h2&gt;
&lt;p&gt;Bem, agora estou estudando ele, praticamente todos os dias, pois j&amp;aacute; utilizo ele em projetos que est&amp;atilde;o em produ&amp;ccedil;&amp;atilde;o. Mas pretendo ir al&amp;eacute;m, utiliz&amp;aacute;-lo da forma como fiz com este blog, quero melhorar contribuir com a comunidade e se surgir alguma id&amp;eacute;ia legal desenvolvo algo &amp;uacute;til para compartilhar com o mundo open-source, mundo este que me conquista cada vez mais. :)&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/meu-primeiro-pequeno-projeto-desenvolvido-utilizando-django/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/meu-primeiro-pequeno-projeto-desenvolvido-utilizando-django/</feedburner:origLink></item><item><title>Fatos que me transformaram em um programador melhor!</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/31wVzwelMsI/</link><description>&lt;p&gt;&lt;em&gt;Eu e meus textos gigantes.. mas vou ser bonzinho, se estiver com pressa &amp;eacute; s&amp;oacute; passar pro &lt;a href="#sintetizando-o-artigo"&gt;fim&lt;/a&gt; que l&amp;aacute; eu sintetizo o artigo.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ser programador &amp;eacute; dif&amp;iacute;cil! &amp;Eacute; melhor come&amp;ccedil;ar assim do que falar que &amp;eacute; "f&amp;aacute;cil" e que qualquer um pode ser, pois &amp;eacute; a&amp;iacute; que se encontra uma das desilus&amp;otilde;es dos alunos de cursos de inform&amp;aacute;tica, ponto de vista meu e esse nem &amp;eacute; o assunto, ent&amp;atilde;o vamos ao que interessa!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Eu programo em $%#$%$@ e tenho uma super IDE onde eu clico em "gerar programa" e ela faz sozinha, publica e ainda manda um SMS para o cliente avisando que est&amp;aacute; no ar.&lt;br /&gt;-- Autor desconhecido. (ou conhecido seu, talvez)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Meu objetivo n&amp;atilde;o &amp;eacute; criticar quem gosta do autom&amp;aacute;tico de tudo com o mouse ou qualquer coisa do tipo, ali&amp;aacute;s acho super interessante se eu tiver de criar um programa em JAVA, por exemplo, usando JPA, no netbeans, para uma aplica&amp;ccedil;&amp;atilde;o simples e r&amp;aacute;pida que nem quero mexer em c&amp;oacute;digo. Com alguns cliques a interface est&amp;aacute; pronta e interagindo no banco de dados, pronta para rodar cross-plataform.&lt;/p&gt;
&lt;p&gt;Mas quero falar sobre mim, por onde passei e onde estou.&lt;/p&gt;
&lt;p&gt;&lt;img class="img_center" title="Evolu&amp;ccedil;&amp;atilde;o" src="http://media.douglasmiranda.com/uploads/artigos/5727278512_fc69d55df6_b_large.jpg" alt="Evolu&amp;ccedil;&amp;atilde;o" width="680" height="256" /&gt;&lt;/p&gt;
&lt;p&gt;Como uma grande parte dos iniciantes em desenvolvimento de aplica&amp;ccedil;&amp;otilde;es web, dei in&amp;iacute;cio recortando layout no photoshop e "codando" html, css, javascript e php no Dreamweaver, esse foi o in&amp;iacute;cio, e olha que no in&amp;iacute;cio usava tabela pra layout, (such a shame). Em um certo momento achei super legal o lance que o NetBeans oferecia de suporte para programar, at&amp;eacute; fiquei mais "burro" porque ele completava at&amp;eacute; o que n&amp;atilde;o precisava, ainda mais na vers&amp;atilde;o que passou a integrar com Zend Framework. Sem contar que ele "chupa" uma mem&amp;oacute;ria e processamento que n&amp;atilde;o &amp;eacute; brincadeira!&lt;/p&gt;
&lt;p&gt;Bem at&amp;eacute; a&amp;iacute; eu j&amp;aacute; sabia programar pra resolver problemas, e terminar o job. Mas sentia essa diferen&amp;ccedil;a entre o que eu tinha em mente e utilizava durante o dia e o que eu lia em artigos de programadores de renome.&lt;/p&gt;
&lt;p&gt;Foi ent&amp;atilde;o que decidi mudar radicalmente, instalei o Linux, passei a usar um editor de texto mais simples s&amp;oacute; com o necess&amp;aacute;rio, por&amp;eacute;m personaliz&amp;aacute;vel para quando eu quisesse algo mais, uso o Sublime Text 2 no momento, queria mudar para o Vim, mas ainda n&amp;atilde;o consegui. :)&lt;/p&gt;
&lt;p&gt;Ent&amp;atilde;o vi a oportunidade de aprender outra linguagem, escolhi Python. Logo mais ap&amp;oacute;s me familiarizar com Python comecei estudar o Django e c&amp;aacute; estou escrevendo este post em um blog que fiz em Django. :D&lt;/p&gt;
&lt;p&gt;Ahh, come&amp;ccedil;ar a utilizar git/github, treinar resolvendo desafios, como os do Project Euler e ficar implementando ideias que tenho s&amp;oacute; pra ver como que funciona, me ajudou bastante tamb&amp;eacute;m.&lt;/p&gt;
&lt;p&gt;Dentre estes t&amp;oacute;picos citados no texto houveram pequenos detalhes que foram me moldando com o tempo, &amp;eacute; claro, mas no geral, sintetizando o texto acima&lt;a name="sintetizando-o-artigo"&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Conhecer um pouco das diversas formas de se desenvolver para web.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Utilizar, avaliar e abandonar as ferramentas que estavam auxiliando somente terminar um servi&amp;ccedil;o e n&amp;atilde;o estava agregando conhecimento e valoriza&amp;ccedil;&amp;atilde;o profissional que eu queria. A IDE e/ou editor de texto, fazem muito a diferen&amp;ccedil;a.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mudar para o ambiente em que as aplica&amp;ccedil;&amp;otilde;es que eu fa&amp;ccedil;o rodam, isto &amp;eacute;, quando passei a utilizar o Linux, n&amp;atilde;o sou "o cara" do bash ainda, mas me viro. Foi bom at&amp;eacute; que quando falo com o suporte de hospedagens, &amp;agrave;s vezes, at&amp;eacute; dou as poss&amp;iacute;veis solu&amp;ccedil;&amp;otilde;es para o problema que quero que eles resolvam j&amp;aacute; que comecei conhecer a plataforma na pr&amp;aacute;tica.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Caraca, Project Euler pra treinar e conhecer o b&amp;aacute;sico do Python foi muito bacana. Ali&amp;aacute;s para qualquer linguagem &amp;eacute; bem legal!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;O git, por mais que eu seja iniciante, est&amp;aacute; me ajudando muito. Muito mesmo!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Por &amp;uacute;ltimo e n&amp;atilde;o menos importante s&amp;atilde;o dois detalhes: conhecer novas pessoas da sua &amp;aacute;rea dispostas a te ajudar.&amp;nbsp; E outra coisa, voc&amp;ecirc; ajudar pessoas que est&amp;atilde;o iniciando tamb&amp;eacute;m, isto &amp;eacute; muito bom, pois para ensinar, voc&amp;ecirc; ter&amp;aacute; de saber. =)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;Eacute; isso a&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Nota mental: &lt;em&gt;Diminuir o tamanho dos textos =~&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Fonte imagem: &lt;a href="http://www.flickr.com/photos/hikingartist/5727278512/" target="_parent"&gt;link&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/fatos-que-me-transformaram-em-um-programador-melhor/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/fatos-que-me-transformaram-em-um-programador-melhor/</feedburner:origLink></item><item><title>Hello, world!</title><link>http://feedproxy.google.com/~r/douglasmiranda/~3/vvzDCXQUWLY/</link><description>&lt;p&gt;&lt;img class="img_center" src="http://media.douglasmiranda.com/uploads/artigos/imagens/472097903_b781a0f4f8_big.jpg" alt="Hello, World!" width="460" height="345" /&gt;&lt;/p&gt;
&lt;p&gt;Bem, como digo no &lt;a href="/me/"&gt;texto sobre mim &lt;/a&gt;eu estou aprendendo &lt;strong&gt;Python/Django&lt;/strong&gt; e nada melhor do que colocar a teoria em pr&amp;aacute;tica, para tal criei este blog que utilizarei para compartilhar experi&amp;ecirc;ncias, opini&amp;otilde;es, entre outros.&lt;/p&gt;
&lt;p&gt;At&amp;eacute; por isto pode haver v&amp;aacute;rias mudan&amp;ccedil;as e refatora&amp;ccedil;&amp;otilde;es que poder&amp;atilde;o ser visualizadas no reposit&amp;oacute;rio &lt;a class="external" title="Reposit&amp;oacute;rio deste blog no github" href="https://github.com/douglasmiranda/douglasmiranda.com" target="_blank"&gt;deste blog&lt;/a&gt; no &lt;a class="external" href="https://github.com/douglasmiranda"&gt;meu github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Eu programo, ent&amp;atilde;o n&amp;atilde;o sou "o cara" do design, por isto utilizei este free layout que &amp;eacute; disponibilizado em um artigo da Smashing Magazine.&lt;/p&gt;
&lt;p&gt;O que aprendi de Python e Django at&amp;eacute; agora pra desenvolver este blog foi gra&amp;ccedil;as as dicas que &lt;strong&gt;Andrews Medina&lt;/strong&gt; me deu, li boa parte do livro &lt;strong&gt;Think Python&lt;/strong&gt;, a documenta&amp;ccedil;&amp;atilde;o do Python, uma treinada b&amp;aacute;sica nos desafios do &lt;strong&gt;Project Euler&lt;/strong&gt;, artigos e materiais que encontrei na web.&lt;/p&gt;
&lt;p&gt;Em Django fiquei surpreso com o qu&amp;atilde;o esclarecedora &amp;eacute; a documenta&amp;ccedil;&amp;atilde;o deste framework, fiz o tutorial do Django tamb&amp;eacute;m, foi muito bom para aprender. At&amp;eacute; tive umas d&amp;uacute;vidas se usava as &lt;strong&gt;class-based generic views&lt;/strong&gt;, ent&amp;atilde;o &lt;strong&gt;Mayza de Oliveira&lt;/strong&gt; me deu a dica de usar "pra tudo" e compreendi rapidamente o uso, &amp;eacute; bem bacana :)&lt;/p&gt;
&lt;p&gt;&amp;Eacute; isto, vou tentar ser o mais breve poss&amp;iacute;vel nos artigos e escrever com qualidade. Cr&amp;iacute;ticas, sugest&amp;otilde;es e coment&amp;aacute;rios s&amp;atilde;o sempre bem-vindos.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;See ya in anotha life brotha!&lt;br /&gt;-- Desmond - Lost&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Fonte da imagem - &lt;a class="external" href="http://www.flickr.com/photos/oskay/472097903/" target="_blank"&gt;link&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://douglasmiranda.com/artigo/hello-world/</guid><feedburner:origLink>http://douglasmiranda.com/artigo/hello-world/</feedburner:origLink></item></channel></rss>

