<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
	<title>Blogs en español de la Comunidad Django.</title>
	<link>http://django.es/comunidad/</link>
	<description>Blogs en español de la Comunidad Django.</description>
	<language>es</language>

	<item>
	<title>¿Cómo integrar formularios en la administración de Django? django-form-admin</title>
	<author>Yaco</author>
	<link>http://www.yaco.es/blog/django/2012/05/how-to-integrate-forms-in-the-django-admin-site/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=how-to-integrate-forms-in-the-django-admin-site</link>
	<guid>http://www.yaco.es/blog/django/2012/05/how-to-integrate-forms-in-the-django-admin-site/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=how-to-integrate-forms-in-the-django-admin-site</guid>
	<pubDate>mar, 15 May 2012 00:00:00 +0200</pubDate>
	<description>Es habitual que deseemos añadir alguna funcionalidad para los super usuarios de nuestro sitio web, y es normal que de hacerlo elijamos la administración para ello. En muchas ocasiones intentaremos que dicho usuario no note que realmente (programáticamente) está fuera de la administración de Django, para ganar experiencia de usuario, con lo [...]</description>
	</item>

	<item>
	<title>vim tips</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/04/09/vim-tips/</link>
	<guid>http://trespams.com/2012/04/09/vim-tips/</guid>
	<pubDate>lun, 9 Abr 2012 00:00:00 +0200</pubDate>
	<description>He actualitzat la configuració que faig servir per a fer feina amb Vim per programar amb Python i Django a partir de l&#39;article de sontek, llevant coses que no faig servir o que m&#39;agrada més tenir en una consola: py.test, git, etc. i afegint algunes definicions que m&#39;han anat molt bé a llarg dels anys. Ho podeu trobar a http://code.google.com/p/trespams-vim/
La millora més important és la descoberta de Pathogen, que ens permet gestionar millor els plugins i del plugin gundu que ens permet veure els canvis a un fitxer, com si fos un control de versions local.
Manteng cla configuració de backup i com que tinc força memòria als ordinadors que faig servir tenc llevat també el swapfile.
Aquest punt em servirà com a recordatori de combinacions de tecles útils a més de les habituals de vim.
Tecla leader. Surt per tot a vim. Mapejada a coma (,)
Tancar la finestra quickfix ,cc
Anar a una finestra: ctrl+jklh
Veure els registres: ,r
Copiar a un registre texte seleccinat: &quot;y
Aferrar des d&#39;un registre &quot;&lt;registre&gt;p&quot;
Mostrar la finestra de canvis: `g
Canvia el directori de treball: ,.
Executa el validador PEP8 ,8
Veure els marcadors: :marks
Estableix un marcador m
Ves a una marca &#39;&lt;lletra&gt; (o accent greu + marca per anar al lloc exacte on s&#39;establí. 
Obrir un buffer: :e 
Tancar un buffer: :bq o bé :bw
Vim és tot un món, hi ha combinacions i plugins a voler. Personalment crec que el truc éstà en anar aprenent a poc a poc, perimer amb el més bàsic i després amb totes aquestes virgueries fins anar configurant un entorn on ens hi trobem còmodes.
Posant la nostra configuració a un sistema de control de versions, disposar de la nostra configuració local és trivial.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Emprenedors</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/03/19/emprenedors/</link>
	<guid>http://trespams.com/2012/03/19/emprenedors/</guid>
	<pubDate>lun, 19 Mar 2012 00:00:00 +0200</pubDate>
	<description>Aquests darrers dies he tingut moltes reunions, la majoria emprenedors que volien demanar un pressupost per al seu projecte. I és aquest fet el que motiva aquest article, ja que amb totes aquestes reunions i amb altres que he tingut abans, hi ha força punts en comú i convé reflexionar-hi
Sóc un emprenedor
Enhorabona! Jo també. Per mi un emprenedor és un projecte d&#39;empresari. És a dir, algú que té una idea de negoci i que ha de demostrar-ne la seva viabilitat i aconseguir posar-lo en marxa.
El que he vist és que hi ha gent que fa servir aquest concepte com a sinònim de &quot;no tenc pressupost&quot; o &quot;no et puc pagar per la teva feina&quot;. Amb això ja començam malament. Primer perquè per poder menjar i mantenir el meu propi projecte, jo necessit cobrar la feina, que això de la informàtica potser t&#39;omple espiritualment, però no t&#39;omple la panxa.
Més enllà de l&#39;anècdota, crec que tota aquesta publicitat de converteix-te en emprenedor més enllà de la visió romàntica també hauria de tractar aspectes pràctics. Que en les n-mil conferències i trobades es tracten molt per damunt els problemes reals. Emprendre també té un component de viabilitat econòmica, el pla de negoci que s&#39;ha d&#39;avaluar, s&#39;han de saber d&#39;on sortiran els recursos. Suposar que algú ens farà la feina gratis és, ja d&#39;entrada, menysprear la feina que farà l&#39;altra.
Vull dir, si la teva idea és molt bona, però no hi vols arriscar doblers, demanar a algú que faci feina per tu, i que hi posi la seva feina (que vol dir doblers indirectament) a canvi de un futurible, o d&#39;un &quot;ja cobraràs quan el negoci funcioni&quot; per mi ja directament descarta el projecte. Si tu ja arrisques doblers, jo puc veure que t&#39;ho la prens seriosament, i llavors puc contemplar fer feina per manco de la tarifa habitual o a posar-hi hores de manera gratuïta a canvi d&#39;una participació a l&#39;empresa. Però com dic, el risc ha d&#39;estar equilibrat, i el programador o l&#39;empresa de programació no pot assumir el risc del negoci.
Emprendre un negoci en el món de la informàtica amb unes mínimes garanties d&#39;èxit no es pot fer sense pressupost. Segons el projecte serà més gran o més petit, però si no ets directament que fa el producte i el comercialitza, hauràs de pagar algú per a que et desenvolupi el producte. Però no tan sols això, has de pagar les despeses de l&#39;empresa, de hostejar els servidors, del lloguer, telèfon, ... 
Si la idea és molt bona, llavors hem de pensar que segurament algú en aquell precís moment potser també la té. I per tant, treure el projecte o no és una qüestió de qui serà el primer, o de qui pot suportar millor les pèrdues.
Personalment crec que la gent que va muntar Amazon per exemple, també eren emprenedors, però la seva idea de negoci i de ser els primers era tan clara que els primers anys gastaren gran quantitat de diners per tal de garantir que ningú altra podria seguir el seu ritme.
Així doncs, emprendre en un negoci online, sense tenir un mínim pla de negoci i uns recursos per a subsistir i aguantar una temporada és poc menys que suïcida. La setmana passada, i em va saber molt greu, em vaig trobar fent un mini-pla-de-negoci en 5 minuts per tal de demostrar a aquella persona, que venia tota il·lusionada que la seva idea sense un bon finançament no era viable. Tenir que ser tu que facis tocar de peus a terra la gent que te ve amb una idea no és gens divertit.
Senyors que organitzau conferències de recolzament a emprenedors, per favor, no aneu dient que tot és un camí de roses. Parlar de rondes de finançament, de grans números us fa quedar molt bé, però la crua realitat és una altra. Al nostre país és molt complicat trobar inversors, és molt complicat muntar un negoci online, tot són entrebancs: des de les passarel·les de pagament del segle passat, a la legislació que et ferma de peus i mans i no et deixa competir amb legislacions molt més orientades a negoci com l&#39;anglosaxona.
El projecte el farà un freelance.
Tens una idea, la idea es bona i hi ha un poc de finançament. Però com que ets un emprenedor la feina te la fa un freelance. Eps! Cap problema, conec freelance força bons. El problema, és que això és sinònim de dir que &quot;m&#39;ho fa un paio i surt a un preu molt baix&quot;. 
S&#39;està pensant a molt curt plaç. No vull dir que no es tengui que mirar el preu, sinó que si el teu negoci dependrà del desenvolupament que et faci algú extern s&#39;ha de pensar també amb la continuïtat del projecte. Els freelance bons són cars i van cercats. Si no és així és que quelcom falla. A un sector on no hi ha pràcticament atur, que algú faci feina per molt menys del preu de mercat a mi personalment em feia sospitar quan era a &quot;l&#39;altra costat&quot;.
Quan un empren i una bona part del seu negoci estarà basat en una aplicació web s&#39;ha d&#39;assegurar en el que pugui la continuïtat del desenvolupament. S&#39;ha de preveure que hi haurà canvis, errors, adaptacions que algú haurà de fer. I en desenvolupament hem de pensar que agafar codi d&#39;algú altra és molt més costos que si has de mantenir codi que ja coneixes o que està fet d&#39;acord amb uns estàndards definits.
Potser pel teu negoci un freelances serà el que necessites, però al manco ho has de tenir clar i avaluar-ne els riscs. Contractar algú com a freelance sols pel fet que surt més barat és estar assumint un risc molt gran que pot posar en perill el negoci.
Com m&#39;ajudarà Django?
Ja ho tenim clar, tenim pressupost i tenim clar el perquè hem triat aquella empresa o aquell desenvolupador freelance. La tecnologia amb el que un desenvoluparà l&#39;aplicació web de la seva startup també té importància. Hem de tenir en compte dues coses: la facilitat per fer modificacions i l&#39;escalabilitat.
Pensem que quan posam en marxa el nostre negoci poques vegades el que hem pensat funciona a la primera. Hem de fer adaptacions tant al model de negoci com a la tecnologia. I això ho dic també per pròpia experiència. La manera de fer les coses que teníem fa 4 anys no és la mateixa que tenim ara. Ens hem tingut que anar adaptant a les necessitats dels nostres clients per a poder donar-los servei. En alguns casos amb inversions internes de mesos i és un procés que no s&#39;acaba mai (o que no s&#39;hauria d&#39;acabar mai).
Per això és molt important que la tecnologia que facem servir ens permeti desenvolupar ràpid, però sobretot que ens deixi fer modificacions i posar-les en producció tant o més ràpid que fent el desenvolupament des de zero.
Per què hem triat i recomanam Django? Doncs per això mateix. Django separa el que és la base de dades, del model de dades, regles de negoci i capa de presentació. Això vol dir que podem minimitzar l&#39;impacte dels canvis, limitant-los a la capa necessària de l&#39;aplicació. Ens permet escalar amb gent i separar rols de desenvolupament, la qual cosa ens permet desenvolupar i mantenir aplicacions grans amb un equip reduït de gent i mantenir els costs continguts.
L&#39;estructura de desplegament de Django ens permet escalar l&#39;aplicació afegint més servidors. Utilitats com Celery ens permeten distribuir tasques entre servidors, uWSGI, ngnix, redis, memcached, ... Hi ha tot un ecosistema de petites aplicacions altament especialitzades que treballen de manera harmoniosa i que ens permetran anar afegint més servidors i més potencia a la nostra aplicació així com aquesta ho necessiti, escalant per alt però també per baix.
Quan un desenvolupa amb Django de fet està desenvolupant amb Python (més HTML, més CSS, més Javascript) i si ha una cosa que caracteritza Python és la seva legibilitat i facilitat de manteniment.
Amb una estructura adequada per a dur els projectes, tenir que fer modificacions a un projecte passa de ser un malson a convertir-se en una tasca més. Acabam interioritzant dins l&#39;empresa (la del client) que evolucionar és normal, que no hi ha problema, que no és un trasbals. Que es poden fer canvis, veure com funciona i si no ho fan desfer-los, ...
És la tecnologia elegida, junt a l&#39;equip que la fa servir, el que ens permet estar tranquils quan hem de fer un canvi. Hi ha tecnologies que cada pas a producció és un esdeveniment que s&#39;ha de planificar amb molta antelació, on sols es poden provar canvis cada cert temps perquè fer el desplegament és molt car, que no escalen cap avall  el cost de mantenir un entorn de proves és prohibitiu.
Python i Django eliminen molts maldecaps i ens permeten estar tranquils. Però no us vull enganar, fer les coses pensant en el futur sempre té el seus cost. S&#39;han de fer plans, s&#39;han de pensar les coses per a que siguin testejables i mantenibles, no és un codificar com a un boig i ja veurem què sortirà, o codificar pensant que ja ho mantindrà un altra.
Emprendre amb seny
Així doncs si la vostra nova startup té un component informàtic important, sia web o no, pensau que hi ha un munt de coses a tenir en compte a més de la idea. Que la tecnologia compta, que l&#39;equip que tens al darrera compta i que encara que no es digui massa a les conferències fer números i tirar de fulla de càlcul és molt important.
Per la meva banda potser em seguirà tocant de tant en tant desil·lusionar algú, però crec que ja he s&#39;ha pres la molèstia de venir a fer una xerrada o demanar un pressupost, el mínim que puc fer és avisar-lo si veig alguna cosa que no encaixa. 
No sé si fer d&#39;advocat del diable, però el cert és que crec que si el projecte ha d&#39;anar endavant un punt fonamental de la relació client-proveïdor ha de ser l&#39;honestedat, i això fa que si veig alguna cosa que pot posar en risc el projecte o que el projecte no és viable, convé posar-ho damunt la taula tan aviat com es coneix.
Pens que tract a la gent com m&#39;agrada que em tractin a mi.

2 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Se buscan buenos programadores</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/03/04/se-buscan-buenos-programadores/</link>
	<guid>http://trespams.com/2012/03/04/se-buscan-buenos-programadores/</guid>
	<pubDate>dom, 4 Mar 2012 00:00:00 +0100</pubDate>
	<description>Hi ha una frase que diu que &quot;a Internet ningú saps que ets un ca&quot;. El 
mateix es pot dir actualment del llenguatge de programació que mou una 
plana o aplicació web, mentre la plana faci el que ha de fer, a 
l&#39;usuari que l&#39;està utilitzant no l&#39;interessa el més mínim amb què 
està feta.
Que avui en dia les planes acabin en php, asp, .do, no deixa de ser 
anecdòtic. Els bastiments de programació més moderns fins i tot 
amaguen amb què està feta la web a simple vista, a l&#39;usuari no li cal 
la informació i potser estàs donant massa informació a algun 
visitant no desitjat.
Aquest apunt ve arrel d&#39;un post a bonillaware, titulat se buscan 
buenos programadores. El post és força intressant i l&#39;oferta de feina crec que també, però allà 
faig una petita reflexió: no entenc com una companyia que va de cools 
pot fer un error tan de base com cercar bons programadors en un 
llenguatge concret. Bé, ho entenc si el que cerques no són bons 
programadors, sinó gent experimentada amb una tecnologia en concret.
Vuit anys d&#39;experiència no et converteixen en un bon programador en 
res. Si no has après el que s&#39;havia d&#39;aprendre els dos primers anys, 
afegir anys d&#39;experiència sols pot fer que segueixis repetint sempre 
els mateixos errors.
Però bé, fent aquesta reflexió va hi bota algú que es sent 
profundament al·ludit. Potser no m&#39;he explicat bé, però la idea és 
que si t&#39;agrada la programació has de ser capaç de veure les 
mancances tant de Java com de qualsevol altra llenguatge de 
programació. Mancances i punt forts és clar. I si t&#39;agrada molt 
programar i tens un mínim d&#39;inquietud pel que fas, arribes a la 
conclusió que Java no és ni d&#39;un bon tros el millor llenguatge per 
fer programació web.
Al comentari diu &quot;de lo que se trata es de abstraer la realidad y  modelarla en un lenguaje que las máquinas sean capaz de procesar&quot;. 
Cert, això queda molt bé, però per la mateixa raó que descartam 
fer-ho amb binari, l&#39;eina que triam per fer una tasca concreta té 
molta importància. No es tracta d&#39;això de fet, es tracta de fer la 
feina de manera que sigui divertit fer-la, però també que sigui 
rendible, és a dir, que no ha de tenir un cost per damunt del retorn 
de la inversió i a més s&#39;ha de poder mantenir i depurar amb facilitat.
En Bonilla no s&#39;atura al fons de la qüestió, que és el perquè 
l&#39;empresa que fa l&#39;oferta ho fa en termes que contradiu la seva pròpia 
imatge, sinó que entra en la &quot;guerra&quot; del llenguatge &quot;Yo prefiero 
divertirme haciendo cosas, no con el lenguaje con el que las hago&quot;.
Si hem d&#39;anar per aquí jo vull triar les dues coses. Vull divertir-me 
amb els projectes, però a més vull divertir-me fent servir les eines 
que m&#39;agraden. Per això faig feina amb Python, Django i Linux i no amb 
altres eines, perquè amb això amb diverteixo fent els projectes. 
Segurament podria guanyar molt més com a programador o cap de projecte 
Java (de fet guanyava més que ara), però no em divertiria tant.
Personalment em motiva molt que els temps entre la idea i la posada en 
producció s&#39;acurcin, no tenir que fer sobrearquitectures, poder 
encaixar i triar les millors peces. Tenir eines potents de 
desenvolupament i depuració.
Java no és un mal llenguatge, o no ho era, ara ja l&#39;han complicat 
massa. Per a la web la cosa encara està pitjor, es pot fer de tot, és 
veritat, però no amb la facilitat i eficiència d&#39;altres llenguatges. 
Si anau pels apunts antics del blog hi veureu posts dedicats a 
Hibernate i Spring, escrits quan la gent ens mirava com a &quot;rarets&quot; 
quan dèiem que Struts no era &quot;la manera&quot; de fer les coses i que hi 
havia tecnologies millors.
En l&#39;època que vaig estar a càrrec dels projectes webs de TUI 
España, record que fins i tot ens vàrem fer la típica &quot;encerrona&quot; 
amb gent de Thales per tal d&#39;esbrinar si el que deiem era cert o no. 
Això de fer servir Ant pels desplegaments, control de versions, Tomcat 
enlloc de JBoss, Linux per als servidors, amb Apache al davant, 
Hibernate per a la part de persistència, Spring com a MVC i IoC i 
JSP-EL a la capa de presentació, era massa per gent acostumada a fer 
feina amb Oracle Forms i on el concepte de codi compartit que es tenia 
era una carpeta compartida Windows amb una fulla de càlcul.
Amb el vist-i-plau de Thales que no va tenir més remei que reconèixer 
que ells estaven començant a fer servir el mateix (quan nosaltres ja 
dúiem un grapat de projectes entregats) vam anar desenvolupant webs 
per TUIE.
La cosa, però és que cada cop el negoci requeria d&#39;un temps de 
resposta més curt. El negoci turístic, com tants d&#39;altres, necessita 
les coses, per ahir, i tot i que el nivell de desenvolupament 
Java-J2EE era prou bo, començarem a mirar cap a altres tipus d&#39;eines 
que ens permetessin donar un temps de resposta millor. Rails 
començava a apuntar maneres i tot l&#39;equip va anar a fer un curs a la 
CAEB, que per cert impartia Guillem Cantallops.
També era l&#39;època de l&#39;alliberament de Django. També apuntant molt 
bones maneres i fet amb Python. Vam avaluar les dues possibilitats, 
PHP ho descartàrem gairebé des del principi, massa emperons. Havíem 
fet el curset de Rails i els exemples i vam fer els primers prototips 
amb Django. 
Juan (a.k.a @morenosan), com jo mateix, ja teníem experiència fent 
feina amb Python i sabíem de les possibilitats d&#39;aquest llenguatge. 
Històricament les projectes Python van evolucionant molt bé, ja que 
el llenguatge és molt llegible i facilita la incorporació de nous 
programadors als projectes. Podíem haver tirat cap a Ruby i Rails, 
però ens sentíem més còmodes amb Python i Django així que tiràrem 
cap allà. El nombre de projectes webs que poguérem treure és 
multiplicà i el temps de posada en producció era senzillament ridícul.
Alguns projectes els reférem des de zero per a reduir-ne el 
manteniment. A més de poder-los fer en una fracció del temps i de 
codi, resultà que a més el rendiment era molt millor. La 
sobrearquitectura de Java estava fent molt de mal.
Va ser una època molt bona, però hi havia maror per ca&#39;n TUI. 
Consultors de recursos humans que deien als desenvolupadors que &quot;la 
mejor opción es irse&quot; es van sumar a tot el que significa un procés 
de fusió amb HotelBeds.
A HotelBeds hi vaig trobar gent molt bona, però després d&#39;estar-hi 
gairebé mig any em vaig trobar com al principi amb TUI, sols que 
aquesta vegada l&#39;immobilisme era encara major. Condemnats a no fer res 
nou, a fer feina amb tecnologia obsoleta i/o propietària em vaig 
plantejar un canvi radical d&#39;aires. APSL va sorgir de l&#39;aposta per la 
tecnologia, per divertir-se programant i fent projectes.
Què el llenguatge de programació no importa? Sí que importa, importa 
si t&#39;agrada el que fas i la programació no és una manera de passar 
hores davant un teclat com qui veu créixer l&#39;herba. Importa si ets una 
consultora interessada en facturar el més possible, en aquest cas 
millor triar Java, .Net o posar TIBCO per orquestrar serveis que 
encara no tens. Importa si et dediques a la programació Copperfield, 
&quot;entrego el programa y desaparezco&quot;, en aquest cas segurament el PHP 
t&#39;anirà d&#39;allò més be.
Però si t&#39;agrada la programació la teva maledicció serà que no et 
conformaràs mai. Sempre cercaràs maneres de fer millor les coses, 
llenguatges que provar per si són millors que el que fas servir ara. 
Noves llibreries, nous editors, noves eines. Seràs un inconformista, 
un tocacollons si m&#39;apures, però recorda que l&#39;evolució tècnica 
(potser tota l&#39;evolució) prové precisament de gent que no es conforma amb el que hi ha.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views - Epílogo</title>
	<author>APSL en blog</author>
	<link>http://blog.apsl.net/weblog/2012/03/03/django-class-based-views-epilogo/</link>
	<guid>http://blog.apsl.net/weblog/2012/03/03/django-class-based-views-epilogo/</guid>
	<pubDate>sáb, 3 Mar 2012 00:00:00 +0100</pubDate>
	<description>El mundo de las class based views como se puede ver da para mucho. La posibilidad de sobrescribir funciones, cambiar parámetros e ir combinando mixins hasta obtener la funcionalidad que necesitamos nos permite reutilizar mucho codigo y de manera elegante.
En este último artículo de las serie veremos alguna de las situaciones más habituales en las que nos podemos encontrar y cómo se resuelven.
 
El formulario por defecto no es el que yo quiero.
Es habitual que cuando editamos un objeto mediane un formulario nos encontremos que hay campos que no queremos que se editen. En nuestro ejemplo imaginemos que no queremos que una vez que se ha creado el slug se pueda modificar. Para conseguir esto hemos de crear un nuevo formulario, y dado que queremos tenerlo todo bien organizado crearemos un fichero forms.py y lo pondremos ahí.
class SampleEditForm(forms.ModelForm):
    class Meta:
        model = Sample
        exclude = (&#39;slug&#39;,)

Ahora a la clase que implementa la edición le diremos que utilice éste formulario para editar el objeto:
from forms import SampleEditForm

class SampleUpdateView(UpdateView):
    model = Sample
    success_url = reverse_lazy(&#39;tutorial_list_sample&#39;)
    form_class=SampleEditForm
Quermos poder filtrar/ordenar los resultados.
ListView es un componente ideal para hacer búsquedas y filtros. Con una hoja de estilo y un poco de javascript podemos hacer prácticamente de todo. Para no complicarnos, supongamos que queremos establecer dos filtros: uno para cantidades positivas y uno para cantidades negativas, además de la opción por defecto que será la de mostrar todo. En nuestra plantilla añadiríamos los links correspondientes a los filtros:
&lt;a href=&quot;{% url tutorial_list_sample %}&quot;&gt;All&lt;/a&gt;|
&lt;a href=&quot;{% url tutorial_list_sample %}?filter=positive&quot;&gt;Positive&lt;/a&gt;|
&lt;a href=&quot;{% url tutorial_list_sample %}?filter=negative&quot;&gt;Negative&lt;/a&gt;

y a hora en la clase lo que haremos será extender el método get_queryset de manera que tenga en cuenta si estamos filtrando o no y que aplique el filtro que corresponda en cada caso:
class SampleListView(ListView):
    model = Sample
    paginate_by = 5

    def get_queryset(self):
        queryset = super(SampleListView, self).get_queryset()
        filter = self.request.GET.get(&#39;filter&#39;)
        if filter == &#39;positive&#39;:
            queryset = queryset.filter(ammount__gt=0)
        elif filter== &#39;negative&#39;:
            queryset = queryset.filter(ammount__lt=0)
        return queryset

Como podemos ver en los ejemplo, al final sólo se trta de ir buscando lo que se debe sobreescribir o exteneder para adaptarlo a nuestra necesidades.
No quiero acabar la serie sin referirme a toda la parte de Class Based Views orientadas amostrar información relacionada con fechas. Estas clases se encuentra en django.views.generic.dates y con lo que hemos visto hasta el momento seguro que no tendréis ninguna dificultad para utilizarlas.
Espero que os haya gustado la serie y haber dado un poco más de luz sobre esta excelente oportunidad que nos brinda Django de programar creando código más mantenible, cohesionado y reutilizable.</description>
	</item>

	<item>
	<title>Django class based views - Listados</title>
	<author>APSL en blog</author>
	<link>http://blog.apsl.net/weblog/2012/03/03/django-class-based-views-listados/</link>
	<guid>http://blog.apsl.net/weblog/2012/03/03/django-class-based-views-listados/</guid>
	<pubDate>sáb, 3 Mar 2012 00:00:00 +0100</pubDate>
	<description>En este sexta entrega veremos cómo podemos mostrar listad de objetos, algo que normalmente va muy ligado al flujo de trabajo asociado al CRUD.
Para mostrar listados (paginados o no) Django nos proporciona la clase ListView que podemos encontrar en django.views.generic.list. Esta clase és hija de MultipleObjectTemplateResponseMixin y de BaseListView. Esta última clase es la que hace el grueso del trabajo, ya que es hija de MultipleObjectMixin y de View implementando el método get.
Como en el caso de las vistas oreintadas al trabajo con CRUD también en este caso tenemo una plantilla por defecto, formada por el nombre del modelo y el sufijo &#39;_list&#39;.
Lo que más nos va a interesar normalmente son los métodos y atributos de MultipleObjectMixin. Para empezar no nos complicaremos mucho la vida, mostraremos la lista de los objetos que hemos creado en el post anterior:
A url.py:
url(r&#39;^tutorial/sample/list/$&#39;, SampleListView.as_view(),
    name=&#39;tutorial_list_sample&#39;),

y al views.py podríamos escribir:
from django.views.generic.list import ListView

class SampleListView(ListView):
    model = Sample

Nos queda por definir la plantilla, que tendrá como nombre sample_list.html, pero antes veamos qué variables se van a pasar al contexto de la vista. A saber:
paginator
page_obj
is_paginated
object_list
En contenido de las variables pueden cambiar en función de si tenemos paginación o no, pero las variables serán estas (a no ser que añadamos más, por supuesto). La que más nos interesa ahora es object_list, que contienen la lista de objetos del modelo. De manera que podemos crear una plantilla del tipo:
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Detail List&lt;/h1&gt;
    &lt;table border=&quot;1&quot;&gt;

    {% for sample in object_list %}
    &lt;tr&gt;
        &lt;td&gt;&lt;a href=&quot;{% url tutorial_update_sample sample.slug %}&quot;&gt;
            {{sample.slug}}&lt;/a&gt;&lt;td/&gt;
        &lt;td&gt;{{sample.name}}&lt;td/&gt;
        &lt;td&gt;{{sample.ammount}}&lt;td/&gt;
        &lt;td&gt;{{sample.comments}}&lt;td/&gt;
        &lt;td&gt;
            &lt;a href=&quot;{% url tutorial_delete_sample sample.slug %}&quot;&gt;Delete&lt;/a&gt;|
            &lt;a href=&quot;{% url tutorial_create_sample %}&quot;&gt;Create&lt;/a&gt;
        &lt;/td&gt;
        &lt;/tr&gt;
    {% endfor %}
    &lt;/tr&gt;
    &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
Como en otros ejemplos de plantilla no estoy utiliznando la herencia, el html es muy simple, etc. Lo importante aquí es ver cómo podemos recorrer la lista de objetos para contruir una tabla, y con lo que ya vmos de CRUD podemos enlazar cada objeto con su mantenimiento correspondiente.
A la hora de crear, editar o borrar un registro, podemos elegir entre mostrar dicho registro (si lo tenemos) o bien ir al listando. En este último caso bastaría añadir
success_url = reverse_lazy(&#39;tutorial_list_sample&#39;)a las vista que nos interesen.
Paginación
Normalmente tendremos bastante resultados y es común que los listados se muestren paginados. Para poder hacer esto de manera automática hemos de añadir el atributo paginate_by a la clase, que nos determinará el número máximo de elementos que se mostrarán por página.
 class SampleListView(ListView):
    model = Sample
    paginate_by = 2

Si modificamos así nuestro código y no modificamos la plantilla sólo veremos dos registros. Nos falta todavía añadir los controles de página anterior y página siguiente. Hay numerosos ejemplos de cómo mostrar la paginación, pero por sencillez nos bastaría:
{% if is_paginated %}
        {% if page_obj.has_previous %}
          &lt;a href=&quot;{% url tutorial_list_sample %}?page={{ page_obj.previous_page_number }}&quot;&gt;
             Previous&lt;/a&gt;
        {% endif %}
            &lt;!-- current page --&gt;
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            &lt;!-- end current page --&gt;
        {% if page_obj.has_next %}
         &lt;a href=&quot;{% url tutorial_list_sample %}?page={{ page_obj.next_page_number }}&quot;&gt;
                Next&lt;/a&gt;
         {% endif %}
{% endif %}

Recodemos que hemos deicho que al contexto se pasaba page_object. Fijémonos como esta variable se emplea para acceder a las propiedades de la página actual, el número de páginas totales, saber si una página tiene una página anterior o una posterior y el número que le corresponde.
También hemos hecho uso de is_paginated de manera que no mostraremos la función de paginación si sólo hay una página.
¡Y ya está! Sencillo, ¿verdad?</description>
	</item>

	<item>
	<title>Django Class Based Views - CRUD</title>
	<author>APSL en blog</author>
	<link>http://blog.apsl.net/weblog/2012/03/01/django-class-based-views-crud/</link>
	<guid>http://blog.apsl.net/weblog/2012/03/01/django-class-based-views-crud/</guid>
	<pubDate>jue, 1 Mar 2012 00:00:00 +0100</pubDate>
	<description>En esta qunta parte veremos cómo podemos gestoionar todo lo relacionado con un mantenimiento, el famoso CRUD (Create, Retrieve, Update, Delete). La parte de Retrieve ya la hemos visto, pero volveremos a ella para que nos quede un ejemplo completo. Partiremos del sigueinte modelo:
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name
Django además de DetailView nos proporciona las siguientes clases ya construidas para este tipo de tareias:
CreateView gestiona la creación de objetos
UpdateView gestiona la actualización
Deleteview gestiona el obrrado
Abrochaos los cinturones y haced crujir los dedos, que empezamos!
Creación
Definimos primero la url
url(r&#39;^tutorial/sample/create/$&#39;, SampleCreateView.as_view(),
    name=&#39;tutorial_create_sample&#39;),
Hemos llamado a nuestra clase SampleCreateView así que la definiremos en views.py 
from django.views.generic.edit import CreateView
from main.models import Sample

class SampleCreateView(CreateView):
    model = Sample
Sólo haciendo esto Django ya nos creará internamente un formulario e intentará presentarlo en una planitlla que se contruye con el nombre dle modelo y el sufijo _form. En nuestro caso será sample_form.html, pasándole form como variable de contexto con el formulario creado. Si queremos algo rápido bastaría crear en la plantilla algo así:
 &lt;form action=&quot;.&quot;
            method=&quot;post&quot; accept-charset=&quot;utf-8&quot;&gt;
            {% csrf_token %}
        &lt;table&gt;
        {{form}}
        &lt;/table&gt;
        &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Save &amp;rarr;&quot;&gt;&lt;/p&gt;
    &lt;/form&gt;
Django se encargará de validar el formulario contra nuestro modelo. Es decir, si intentamos introducir en amount un número que no se entero nos generará un error.  Si creáis la plantilla y utilizáis datos válidos e intentáis guardar os dará un error: &quot;No URL to redirect to.  Either provide a url or  define a get_absolute_url method on the Model.&quot; tranquilos, ahora vamos a ello.
Mostrar el objeto
Ya vimos cómo hacerlo en el apunte anterior, pero por completitud lo repetiremos ahora. 
La url:
    url(r&#39;^tutorial/sample/retrieve/(?P&lt;pk&gt;\d+)/$&#39;, 
        SampleView.as_view(),
        name=&#39;tutorial_view_sample&#39;),

y al views.py
class SampleView(DetailView):
    model = Sample

¿Recordáis el error anterior? Bien, para solucionarlo lo que haremos es modificar el modelo para definir get_absolute_url, también podríamos haber definido succes_url o sbreescrito get_success_url, pero este tipo de cosas ya las habíamo visto y mejor variamos un poco, ¿no? Modifiquemos entonces nuestro modelo:
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return (&#39;tutorial_view_sample&#39;, [self.id, ])
En lugar de la clave primaria podemos utiliza el slug, con lo que tendremos urls más amigables, para eso sólo hemos de cambiar el get_absolute_url y la url con la que llamamos a la visualización del objeto. Así:
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return (&#39;tutorial_view_sample&#39;, [self.slug, ])

y la url:
url(r&#39;^tutorial/sample/retrieve/(?P&lt;slug&gt;[-\w]+)/$&#39;, 
    SampleView.as_view(),
    name=&#39;tutorial_view_sample&#39;),

¿Qué hace el permalink? Pues como podéis ver, crea una url para nuestro objeto a partir del nombre que le hemos dado a la url que sirve para visualizarlo. Esto nos permite no tener que escribir las urls directamente &quot;a fuego&quot; en el código, sinó poder hacer referencia a ellas con un nombre dentro de la aplicación.
Si ahora intentáis utilizar el formulario veríes que ya funciona. Podemos crear un registro y cuando lo guardemos nos mostrará el resultado. Tenemos ya dos de las cuatro letras. Veamos las que faltan.
Actualización
La actualización también es muy sencilla. Utilizaremos UpdateView, pero a diferencia de la creación a la url le hemos de pasar bien la clave primaria del objeto o bien su slug (que debe ser único). 
la url:
url(r&#39;^tutorial/sample/update/(?P&lt;slug&gt;[-\w]+)/$&#39;, 
    SampleUpdateView.as_view(),
    name=&#39;tutorial_update_sample&#39;),

como véis, prácticamente idéntico a la url de visualización. En views.py tendríamos:
from django.views.generic.edit import UpdateView

class SampleUpdateView(UpdateView):
    model = Sample
Ahora sólo nos falta enlazar la url para poder ir a la edición del objeto. Podemos acceder a él desde la barra de navegación, pero es mucho mejor añadirlo también en la página web, por ejemplo con un link en la pantalla de visualización para que nos lleve a la edición del objeto. Ya que estamos puestos podremos también el link de creación. Muy resumidamente, nuestro sample_detail.html podría ser de la forma:
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Detail&lt;/h1&gt;
    {{sample.slug}}&lt;br/&gt;
    {{sample.name}}&lt;br/&gt;
    {{sample.ammount}}&lt;br/&gt;
    {{sample.comments}}&lt;br/&gt;

    &lt;a href=&quot;{% url tutorial_update_sample sample.slug %}&quot;&gt;Update&lt;/a&gt;|
    &lt;a href=&quot;{% url tutorial_create_sample %}&quot;&gt;Create&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;
Fijémonos como no codificamos la url directamente, sinó que utilizamos los nombres.
Eliminación
Ya hemos llegado a la última letra del acrónimo. Para borrar un objeto Django nos proporciona la clase DeleteView, que no se limita al obrrado, sinó que nos permite contruir fácilmente el flujo de trabajo consistente en primero pedir confirmación y luego borrar.
La url será de la forma:
url(r&#39;^tutorial/sample/delete/(?P&lt;slug&gt;[-\w]+)/$&#39;,
    SampleDeleteView.as_view(),
    name=&#39;tutorial_delete_sample&#39;),

y a la view.py
from django.views.generic.edit import DeleteView

class SampleDeleteView(DeleteView):
    model = Sample

Si queremos que todo funcione con los nombres por defecto, hemos de crear una plantilla contruida con el nombre dle modelo y el sufijo &quot;_confirm_delete&quot;. En esta plantilla debermos pedir confirmación para borrar el registro, enviando la información a la misma url que utilizamos para la acción inicial pero utilizando POST en lugar de GET. Es decir, la url llamada con GET presenta la confirmación y con POST ejecuta la acción. Veamos un ejemplo de plantilla:
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
    &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Delete&lt;/h1&gt;
    {{sample.slug}}&lt;br/&gt;
    {{sample.name}}&lt;br/&gt;
    {{sample.ammount}}&lt;br/&gt;
    {{sample.comments}}&lt;br/&gt;

    &lt;p&gt;Are you sure?&lt;/p&gt;

    &lt;form action=&quot;.&quot;
            method=&quot;post&quot; accept-charset=&quot;utf-8&quot;&gt;
            {% csrf_token %}
        &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Delete &amp;rarr;&quot;&gt;&lt;/p&gt;
    &lt;/form&gt;

    &lt;p&gt;&lt;a href=&quot;&lt;a href=&quot;{% url tutorial_view_sample sample.slug %}&quot;&gt;Return&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;
Tanto en la creación como en la actualización no hacía falta decirle a Dango dónde queríamos ir, por defecto iba a la visualización del objeto. Ahora estamos borrándolo, por lo que no hay objeto al que ir. Así que obligatoriamente hemos de proporcionar a la clase la url a la que debe ir en el caso de que el objeto se haya eliminado. Lo ideal es enviarlo auna página con todos los registros, pero como todavía no hemos visto cómo hacerlo, de momento lo enviaremos al formulario de creación:
class SampleDeleteView(DeleteView):
    model = Sample
    success_url = reverse_lazy(&#39;tutorial_create_sample&#39;)
Y ya tenemos el CRUD al completo. Nos falta poder visulaizar un listado paginado de registros y hacer alguns acciones básicas más con formularios. Os espero en el siguiente apunte.
 </description>
	</item>

	<item>
	<title>Django Class Based Views - Mostrar un objeto</title>
	<author>APSL en blog</author>
	<link>http://blog.apsl.net/weblog/2012/03/01/django-class-based-views-mostrar-un-objeto/</link>
	<guid>http://blog.apsl.net/weblog/2012/03/01/django-class-based-views-mostrar-un-objeto/</guid>
	<pubDate>jue, 1 Mar 2012 00:00:00 +0100</pubDate>
	<description>Empezamos con este artículo a ver cómo podemos utilizar las Django class based views con los modelos de datos. ¿Verdad que esto se pone cada vez más interesante? Hast el momento hemos visto un uso muy genérico de esta tecnología, pero con lo que ya sabemos deberíamos ser capaces de mostrar páginas web y gestionar el trabajo con formularios.
Es bastante común en las aplicaciones modernas que los datos vengan de algún sitio, es decir, que no estén codificados a fuego en el HTML. Lo más normal es que los datos provengan de una base de datos sql. En su afán de ahorrarnos trabajo los desarrolladores de Django han creado todo un conjunto de mixin y vistas específicas que nos simplifican el trabajo.
Mostrar un objeto.
Supongamos que volemos mostrar la información que tenemos de un usuario. Como sabréis el modelo User de Django guarda los datos de los usuarios y podemos encontrarlo en django.contrib.auth.models. Lo que queremos es que especificando una clave primaria en la url podamos mostrar en nuestra plantailla la información del usuario correspondiente a dicha clave.
Es decir, se trata de mostrar la información que se corresponda con urls de este tipo:
&#39;^prefix/(?P&lt;pk&gt;\d+)/$&#39;

o bien, si trabajamos con slugs
&#39;^prefix/(?P&lt;slug&gt;[-w]+)/$&#39;

Django nos proporciona la clase DetailView para hacer precisamente esto. Es decir, para ahorrarnos la mayor parte del trabajo de buscar el objeto que se corresponda con la clave primaria o slug (lo estoy utilizando como sinónimo de clave única) y pasarlo a la plantilla para su presentación. Por si alguno se lo pregunta DetailView se encuentra en django.views.generic.detail. Veamos cómo es la clase DetailView por dentro:
Esta clase hereda de SingelObjectTemplateResponseMIxin y de BaseDetailView. La primera a suvez es hija de una conocida nuestra TemplateResponseMixin de la que sobrescribe el método get_template_names a fin de establecer un nombre de plantilla pro defecto, que en els caso de los modelos es del tipo app/modelo_detail.html, es decir, en nuestro ejemplo, si no indicamos plantilla, Django la buscará por defecto en auth/user_detail.html.
Por su lado BaseDetailView es hija de SingleObjectMixin y de View e implementa el método get y le pasa al contexto de la plantilla la variable object con el contenido del objeto que se corresponde a la clave única que hemos pasado en la url. Como que trabajar con una variable llamada object puede resultar un tanto confuso, Django también pasa el mismo contenido en una variable que tienen el mismo nombre del objeto si al definir el model hemos establecido el verbose_name, o bien utilizará el que le indiquemos en el atributo context_object_name al definir la clase.
SingleObjectMixin es la clase encargada de hacer el trabajo duro, y como no, también implementa el método get_context_data para poder pasar más información a la plantilla. Así pues, mostrar un objeto puede ser tan sencillo como esto:
A urls.py añadimos:
url(r&#39;^user/(?P&lt;pk&gt;\d+)/$&#39;, UserView.as_view(),
        name=&#39;main_user&#39;),
No olvidemos﻿ importar UserView que crearemos dentro de views.py y que puede ser tan simple como:
class UserView(DetailView):
    model = User
User tiene asignado un verbose_name=&#39;User&#39;. Django por tanto pasa a la plantilla tanto la variable object como la variable user, y por tant, en condiciones normales podríamos utilizar tanto un nombre de varaible como otro.
En nuestro caso, y si como yo tenéis en context_processors la línea &#39;django.contrib.auth.context_processors.auth&#39; os encontrarés que la variable user &quot;no fuciona&quot;. Esto es así porqué el context processor crea también una variable llamada user con los datos del usuario autentificado (si existe) y como se le asigna justo antes de generara la plantilla, el contenido de esta variable prevalicerá sobre el contenido que le pasamos desde la vista. Así pues, primer aviso, si la variable no contienen lo que esperáis vigilad el context_processors.
Una cosa que me sorprendió del SingleObjectMixin es que además del método get_object implementa también get_queryset. De hecho, get_object llama a get_queryset y le aplica un filtro por clave primaria (pk) o por slug. ¿Qué quiere decir eso? Pues sencillamente, que tenemos un nivel extra de flexibilidad a la hora de determinar si un objeto es presentable o no. Basta con sobreescribir o extender el método get_queryset e independientemente de la existencia de la clave única en la base de datos, podemos hacer que el objeto no se muestre. Por ejemplo, supongamos que en el ejemplo anterior no queremos mostrar los datos del usuario admin. Podríamos escribir:
class UserView(DetailView):
    model = User

    def get_queryset(self):
        query = super(UserView, self).get_queryset()
        return query.exclude(username=&#39;admin&#39;)
de manera que UserView nos mostrará la información de cualquier usuario excepto la del usuario admin, en este caso mostraría el error 404.
SingleObjectMixin, como hemos dicho, puede retornarnos un objeto a partir de su clave primaria o bien a partir del slgu. Normalmente utilizamos uno u toro, el orden de prioridad es que primero intenta por clave primaria (pk) y en caso de que este parámetro no exista mirará si tenemos definido el parámetro slug.
En el próximo apunte hablaremos del CRUD.</description>
	</item>

	<item>
	<title>nosehablamas.com.ar | un sitio en 24hs</title>
	<author>Humitos</author>
	<link>http://humitos.wordpress.com/2012/03/01/nosehablamas-com-ar-un-sitio-en-24hs/</link>
	<guid>http://humitos.wordpress.com/2012/03/01/nosehablamas-com-ar-un-sitio-en-24hs/</guid>
	<pubDate>jue, 1 Mar 2012 00:00:00 +0100</pubDate>
	<description>El Martes por la noche me agarró mirando la televisión mientras cenaba. No recuerdo bien la hora, pero estaba mirando TN y el programa que estaban pasando se llamaba “Palabras +, palabras menos”. Sinceramente, no tengo idea de qué se trata, cómo es normalmente ese programa ni ningún otro en realidad, porque no veo televisión. [...]</description>
	</item>

	<item>
	<title>Mandar Archivos dinamicos en una url especifica.</title>
	<author>Zodman</author>
	<link>http://opensrc.mx/post/18496724862</link>
	<guid>http://opensrc.mx/post/18496724862</guid>
	<pubDate>mié, 29 Feb 2012 00:00:00 +0100</pubDate>
	<description>Tengo un pequeños sistema que se encarga de mostrar archivos. Pero eso los sirve en una vista en django. 
Mi primer problema era que abria el archivo con un FileWrapper como se muestra aqui
http://djangosnippets.org/snippets/365/ el problema se encuentra en que a final de cuentas el 
FileWrapper lee el archivos (https://code.djangoproject.com/browser/django/tags/releases/1.3.1/django/core/servers/basehttp.py#L54) Esto quiere decir que si es un archivo muy grande ese 
archivo tiene que ponerlo en memoria para ponerlo  en el response.

Solución:

Usar X-SendFIle

http://djangosnippets.org/snippets/2226/

Con esto te evitas que la aplicacion sirva el archivo subiendolo a memoria mejor se lo pasas al servidor web para que sirva mas rapido!</description>
	</item>

	<item>
	<title>Menor de edad en python / Legal age in python</title>
	<author>Estribancus</author>
	<link>http://www.pvilas.com/2012/02/menor-de-edad-en-python-legal-age-in.html</link>
	<guid>http://www.pvilas.com/2012/02/menor-de-edad-en-python-legal-age-in.html</guid>
	<pubDate>mié, 29 Feb 2012 00:00:00 +0100</pubDate>
	<description>Hoy día 29/02/2012 (29 de febrero de año bisiesto), me he encontrado con que el algoritmo que usaba para el cálculo de minoría de edad me ha fallado. Después de varias indagaciones he dejado este como bueno:from datetime import date, datetime, timedeltadef menor_edad(nascut):  &quot;&quot;&quot; accepts a string date in iso format Y-m-d and returns True if         it is in spanish legal age today &quot;&quot;&quot;  t=timedelta(seconds=31556926*18)  fa_divuit=date.today()-t  fecha=datetime.strptime(nascut, &#39;%Y-%m-%d&#39;).date()  return (fecha &gt; =fa_divuit)</description>
	</item>

	<item>
	<title>Django Class Based Views - TemplateView</title>
	<author>APSL en blog</author>
	<link>http://blog.apsl.net/weblog/2012/02/27/django-class-based-views-templateview/</link>
	<guid>http://blog.apsl.net/weblog/2012/02/27/django-class-based-views-templateview/</guid>
	<pubDate>lun, 27 Feb 2012 00:00:00 +0100</pubDate>
	<description>En esta segunda parte veremos algunos de los usos más interesantes de las class based views para presentar información y ahorrarnos trabajo. En concreto nos concentraremos en 
﻿TemplateView
Como vimos en la primera parte TemplateView nos ahorra mucho trabajo si lo comparamos con la manera tradicionar de hacer las cosas. Sólo por el hecho de que ya se pasa el RequestContext ya recomendaría pasarnoas al nuevo mundo de las Class Based Views, pero os lo perdáis todavía hay más!
TemplateView incormpora dos métodos más get_context_data y get.  El método get lo que hace es llamar al método render_to_response que a su vez nos ha proporcionado el mixin TemplateResponseMixin pasándole como argumentos el diccionario que nos ha de devolver el método get_context_data.
Por defecto get_context_data nos retorna un diccionario con los parámetros que provienen de la url, así si nuestra url es:
 url(r&#39;^test3/(?P&lt;id&gt;\d+)/$&#39;, Test3View.as_view(), 
    name=&quot;test3-class-view&quot;),

entonces get_context_data contendría el diccionario i {&#39;id&#39;: 3} y a la plantilla se pasará una variable llamada params con el contenido de este diccionaro. 
Supongamos por un momento que eso no es exactamente lo que deseamos. Queremos que se pase a la plantilla una variable llamada msg con un saludo para los lectores del blog. Lo que podemos hacer es sobreescribir get_context_data para que pase la información que queremos a la plantilla, de modo que nos quedaría:
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = u&#39;Hello blog!&#39;
        return context
para ser exactos, no haría falta llamar al método padre de  get_context_data y de hecho estamos pasando también la variable params, pero hacerlo así no nos hará mal y por otro lado nos proporciona un grado de protección mayor ante posibles problemas si un día decidimos que Test3View ya no heredará de TemplateView sinó de otra clase, que puede tener ya información en el contexto que nos interese.
En context_data podemos ir añadiendo toda la información que necesitemos. Conviene notar que estamos haciendo prácticamente lo mismo que cuando llamábamos al render_to_template con el método tradicional, sólo que ahora está todo mucho más estructurado.
Rizando el rizo
Supongamos ahora qu elo que queremos no es ya un mensaje fijo, sinó que éste se genera a partir del resultado de una función. Con el método antiguo tendríamos que crear una función en algún lado, unos lo podrían en un módulo aparte, otros com una función dentro de la vista. Ahora podemos aumentar el grado de cohesión de nuestro código encapsulando la funcionalidad dentro de un método de nuestra clase. Así:
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_message(self):
        return u&#39;Hello blog&#39;

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context = dict()
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = self.get_message()
        return context

Y para rematar, gracias al mixin TemplateResponseMixin podemos definir qué plantilla utilizar según nos convenga. Supongamos que el parámetro id nos sirve para definir el nombre de la plantilla, de modo que si existe una plantilla que case con este parámetro y si no que se presente la plantilla por defecto. Podríamos escribir un código como
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_message(self):
        return u&#39;Hello blog&#39;

    def get_template_names(self):
        plantilla = &#39;main/index%s.html&#39; % self.kwargs.get(&#39;id&#39;)
        return [plantilla, ] + super(Test3View, self).get_template_names()

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = self.get_message()
        return context

Como se puede aprecier la potencia y flexibilidad que nos dan las Class Based Views no tienen nada que ver con lo que se podía hacer antes. Ahora tenemos más flexibilidad, más encapsulación y menos código que escribir.
 
Y en el próximo apunte hablaremos de formularios...</description>
	</item>

	<item>
	<title>Filtrado fácil de clave foránea en una ficha de django</title>
	<author>Estribancus</author>
	<link>http://www.pvilas.com/2012/02/filtrado-facil-de-clave-foranea-en-una.html</link>
	<guid>http://www.pvilas.com/2012/02/filtrado-facil-de-clave-foranea-en-una.html</guid>
	<pubDate>vie, 24 Feb 2012 00:00:00 +0100</pubDate>
	<description>Es sabido que django mapea las claves foráneas a un ModelChoiceField en ModelForm, pero ¿qué ocurre cuando sólo queremos seleccionar un subconjunto de ellas?.Por ejemplo, supongamos que estamos dando de alta un empleado y a la hora de seleccionar su categoría sólo queremos que aparezcan las que están asociadas a su sección.Tenemos la ficha:class AddForm(forms.ModelForm):  class Meta:   model=Empleado    fields=(&#39;clave&#39;, &#39;descripcion&#39;, &#39;categoria&#39;, &#39;jefe_seccion&#39;, &#39;email&#39;,)La propiedad queryset del campo categoría estará definida por defecto como Categoria.objects.all(), así que hacemos:p=AddForm()p.fields[&#39;categoria&#39;].queryset=Categoria.objects.filter(seccion=self.seccion)Con lo que en la ficha sólo nos saldrán las categorías de la sección actual.Otra forma más complicada consiste en pasarle el parámetro al constructor de la clase pero hay que hacerlo con los kwargs por que si no tendremos problemas en cuando queramos usar la ficha para editar.class AddForm(forms.ModelForm):          categoria=forms.ModelChoiceField( label=u&#39;Categoría&#39;, queryset = Categoria.objects.none())  def __init__(self, *args, **kwargs):   sec = kwargs.pop(&#39;sec&#39;, None)    super(AddForm, self).__init__(*args, **kwargs)          if sec:            self.fields[&#39;categoria&#39;].queryset = Categoria.objects.filter(seccion = sec)  class Meta:   model=Empleado   fields=(&#39;clave&#39;, &#39;descripcion&#39;, &#39;categoria&#39;, &#39;jefe_seccion&#39;, &#39;email&#39;,)</description>
	</item>

	<item>
	<title>Conectar a un Django shell_plus remoto</title>
	<author>Humitos</author>
	<link>http://humitos.wordpress.com/2012/02/24/conectar-a-un-django-shell_plus-remoto/</link>
	<guid>http://humitos.wordpress.com/2012/02/24/conectar-a-un-django-shell_plus-remoto/</guid>
	<pubDate>vie, 24 Feb 2012 00:00:00 +0100</pubDate>
	<description>¡Acabo de utilizar la cabeza para algo! Todavía estoy emocionado. Creo que esto va a facilitarle las cosas a varios y a reducir ese tiempo tedioso de conectarse al servidor “para probar algo” o “ver qué tiene la db” o etc. La cosa es así, ¿cuántas veces nos logueamos por ssh al servidor para luego [...]</description>
	</item>

	<item>
	<title>Django class based views (VII) - Epíleg</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/24/django-class-based-views-vii-epileg/</link>
	<guid>http://trespams.com/2012/02/24/django-class-based-views-vii-epileg/</guid>
	<pubDate>jue, 23 Feb 2012 00:00:00 +0100</pubDate>
	<description>El món de les class based views dóna per molt, la possibilitat de 
sobreescriure funcions, canviar paràmetres i anar combinant mixins 
fins a obtenir el que necessitam ens permet reutilitzar molt de codi i 
de manera elegant.
En aquest darrer post de la sèrie veurem algunes de les situacions 
més habituals en les que ens podem trobar i la facilitat amb que es 
resolen.
El formulari per defecte no és el que vull
Sovint quan editam un objecte mitjançant un formulari ens trobam que 
hi ha camps que no volem que s&#39;editin. A l&#39;exemple que hem fet servir 
fins ara imaginem que no volem que una vegada s&#39;ha crear l&#39;slug es 
pugui modificar.
Per fer això el que hem de fer és crear un formulari nou. Com que es 
bo tenir les coses organitzades ho farem dins el fitxer forms.py
class SampleEditForm(forms.ModelForm):
    class Meta:
        model = Sample
        exclude = (&#39;slug&#39;,)

i llavors a la classe que implementa l&#39;edició li direm que agafi 
aquest formulari per a editar l&#39;objecte
from forms import SampleEditForm

class SampleUpdateView(UpdateView):
    model = Sample
    success_url = reverse_lazy(&#39;tutorial_list_sample&#39;)
    form_class=SampleEditForm

Volem poder filtrar/ordenar els resultats
El ListView és un component idial per a fer cerques i filtres. Amb una 
fulla d&#39;estils i un poc de javascript podem fer gairebé de tot. Per a 
no complicar-ho massa suposem que el que volem és establir dos 
filtres: un per quantitats positives i un de negatives, a més de 
l&#39;opció per defecte que serà la de mostar-ho tot.
Afegirem els links dels filtres:
&lt;a href=&quot;{% url tutorial_list_sample %}&quot;&gt;All&lt;/a&gt;|
&lt;a href=&quot;{% url tutorial_list_sample %}?filter=positive&quot;&gt;Positive&lt;/a&gt;|
&lt;a href=&quot;{% url tutorial_list_sample %}?filter=negative&quot;&gt;Negative&lt;/a&gt;

i ara a la classe el que farem serà sobrescriure el mètode 
get_queryset de manera que tengui en compte si estam filtrant o no i 
que apliqui el que correspon
class SampleListView(ListView):
    model = Sample
    paginate_by = 5

    def get_queryset(self):
        queryset = super(SampleListView, self).get_queryset()
        filter = self.request.GET.get(&#39;filter&#39;)
        if filter == &#39;positive&#39;:
            queryset = queryset.filter(ammount__gt=0)
        elif filter== &#39;negative&#39;:
            queryset = queryset.filter(ammount__lt=0)
        return queryset

Com es pot veure als exemples al final es tracta de&#39;anar cercant el 
que s&#39;ha de sobreescriure o extendre per a adaptar-lo a les nostres 
necessitats.
No vull acabar la sèrie sense referir-me a tota la part de Class Based 
Views orientades a mostrar informació que ha d&#39;estar relacionada amb 
dates. Aquestes classes es troben a django.views.generic.dates i amb 
el que hem vist de ben segur que no tindreu cap dificultat per a 
fer-les servir.
Esper que us hagi agradat la sèrie i que us sigui profitosa. 
L&#39;objectiu ha estat introduïr aquesta manera de fer les coses i 
organitzar el codi, que per projectes amb un bon grapat de models i 
manteniments, resulta amb menys codi, més ordenat i sobretot més 
mantenible i reaprofitable.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (VI) - Lists</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/23/django-class-based-views-vi-lists/</link>
	<guid>http://trespams.com/2012/02/23/django-class-based-views-vi-lists/</guid>
	<pubDate>jue, 23 Feb 2012 00:00:00 +0100</pubDate>
	<description>En aquesta sisena entrega (que hi ha algú per aquí ho ja us heu 
dormit tots?) veurem com podem mostrar llistes d&#39;objectes que sovint 
podem trobar amb els CRUD.
Per a mostrar llistats (paginats o no) Django ens proporciona la 
classe ListView que es pot trobar a dango.views.generic.list.
Aquesta classe és hereva de MultipleObjectTemplateResponseMixin i de 
BaseListView.
BaseListView és el que la la feina, ja que és fill de 
MultipleObjectMixin i de View implementant-ne el mètode get.
Com les vistes orientades als CRUD també en aquest cas tenim una 
plantilal per defecte, formada pel nom del model i el sufixe &#39;_list&#39;.
El que més ens interessa són doncs els mètodes i atributs de 
MultipleObjectMixin. Primer de tot, però anem a fer-ho fàcil, 
mostrarem la llista dels objectes que hem creat al post anterior:
A l&#39;url:
url(r&#39;^tutorial/sample/list/$&#39;, SampleListView.as_view(),
    name=&#39;tutorial_list_sample&#39;),

i al views.py podem fer 
from django.views.generic.list import ListView

class SampleListView(ListView):
    model = Sample

i ara haurem de definir la plantilla que tindrà com a nom 
sample_list.html, primer, però és convenient conèixer quines 
variables es passen al context, a saber:
paginator
page_obj
is_paginated
object_list
Els valors poden canviar en funció de si tenim paginació o no, però 
les variables que tenim són aquestes. El que ens interessa per ara és 
object_list que conté la llista d&#39;objectes del model. De manera que 
podem fer una plantilla del tipus:
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Detail List&lt;/h1&gt;
    &lt;table border=&quot;1&quot;&gt;

    {% for sample in object_list %}
    &lt;tr&gt;
        &lt;td&gt;&lt;a href=&quot;{% url tutorial_update_sample sample.slug %}&quot;&gt;
            {{sample.slug}}&lt;/a&gt;&lt;td/&gt;
        &lt;td&gt;{{sample.name}}&lt;td/&gt;
        &lt;td&gt;{{sample.ammount}}&lt;td/&gt;
        &lt;td&gt;{{sample.comments}}&lt;td/&gt;
        &lt;td&gt;
            &lt;a href=&quot;{% url tutorial_delete_sample sample.slug %}&quot;&gt;Delete&lt;/a&gt;|
            &lt;a href=&quot;{% url tutorial_create_sample %}&quot;&gt;Create&lt;/a&gt;
        &lt;/td&gt;
        &lt;/tr&gt;
    {% endfor %}
    &lt;/tr&gt;
    &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;

Fixau-vos que no estic fent herència, l&#39;html és molt simple etc. 
L&#39;important aquí és veure com podem recórrer la llista d&#39;objectes per 
montar les files d&#39;una taula, i com amb el que ja sabem del CRUD podem 
enllaçar amb els manteniments.
Ara a l&#39;hora de crear, editar o esborrar un registre podem elegir 
entre mostrar el registre o anar al llistat, afegint 
success_url = reverse_lazy(&#39;tutorial_list_sample&#39;)

a les vistes que ens interessa ja ho tindriem.
Paginació
Com podem tenir molts resultats és comú que les llistes es mostrin 
 paginades. Per fer això el que hem d&#39;afegir l&#39;atribut paginate_by 
 que ens determinarà el nombre màxim d&#39;elements que es mostraran per 
 plana. 
 class SampleListView(ListView):
    model = Sample
    paginate_by = 2

Si fem això i no modificam la plantilla, sols veurem dos registres, el 
que ens falta ara és afegir els controls de plana anterior i plana 
següent. Hi ham moltes maneres de fer la paginació i a la web en 
trobareu un bon munt, però per senzillesa aquest
{% if is_paginated %}
        {% if page_obj.has_previous %}
          &lt;a href=&quot;{% url tutorial_list_sample %}?page={{ page_obj.previous_page_number }}&quot;&gt;
             Previous&lt;/a&gt;
        {% endif %}
            &lt;!-- current page --&gt;
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            &lt;!-- end current page --&gt;
        {% if page_obj.has_next %}
         &lt;a href=&quot;{% url tutorial_list_sample %}?page={{ page_obj.next_page_number }}&quot;&gt;
                Next&lt;/a&gt;
         {% endif %}
{% endif %}

Recordau que hem dit que al context es passava page_object? Doncs 
fixau-vos com es fa servir per saber les propietats de la plana on 
estam, el nombre de planes total, si la plana té una plana anterior o 
una plana següent i el nombre corresponent a aquesta plana.
També fe mus del is_paginated de manera que no mostrem el selector 
de plana anterior i següent si sols hi ha una plana.
I ja ho tenim!
Al proper post, que tancarà la sèrie, veurem com podem limitar la informació que mostram als formularis d&#39;edició

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (V) - CRUD</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/22/django-class-based-views-v-crud/</link>
	<guid>http://trespams.com/2012/02/22/django-class-based-views-v-crud/</guid>
	<pubDate>mié, 22 Feb 2012 00:00:00 +0100</pubDate>
	<description>Creant un CRUD
En aquesta cincquena part veurem com podem crear tot el relacionat amb 
un manteniment, el famos CRUD (Create, Retreive, Update, Delete).
La part de Retreive ja l&#39;hem vista a l&#39;article anterior, però hi 
tornarem per a que ens quedi un exemple complet.
Partirem del següent model:
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name

Django a més de DetailView ens proporciona les següents vistes ja 
construides per fer aquest tipus de tasques:
* `CreateView` que gestiona la creació
* `UpdateView` que gestiona l&#39;actualització
* `DeleteView` gestiona l&#39;esborrat

Comencem!
Creació
Definim primer la url
url(r&#39;^tutorial/sample/create/$&#39;, SampleCreateView.as_view(),
    name=&#39;tutorial_create_sample&#39;),

Hem anomenat a la nostra classe SampleCreateView així que la 
definirem al views.py
from django.views.generic.edit import CreateView
from main.models import Sample

class SampleCreateView(CreateView):
    model = Sample

Amb això Django ja ens crearà internament un formulari i l&#39;intentarà 
presentar a una plantilla que es construeix amb el nom del model i el 
sufixe _form, és a dir, en el nostre cas sample_form.html passant 
com a variable de context el formulari creat form
Si volem fer via amb :
    &lt;form action=&quot;.&quot;
            method=&quot;post&quot; accept-charset=&quot;utf-8&quot;&gt;
            {% csrf_token %}
        &lt;table&gt;
        {{form}}
        &lt;/table&gt;
        &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Save &amp;rarr;&quot;&gt;&lt;/p&gt;
    &lt;/form&gt;

ja ens anirà bé. Django ja se n&#39;encarrega de validar el formulari 
contra el nostre model. És a dir, si posam quelcom que no sigui un 
nombre sencer a amount ens generarà un error.
Si creau la plantilla i posau dades vàlides i intentau guardar us 
donarà un error: &quot;No URL to redirect to.  Either provide a url or 
define a get_absolute_url method on the Model.&quot;, poc a poc i ara hi 
anirem a això.
Mostram l&#39;objecte
Encara que ja ho vàrem veure com es feia al post anterior, per 
completitud, ho farem també ara:
La url:
    url(r&#39;^tutorial/sample/retrieve/(?P&lt;pk&gt;\d+)/$&#39;, 
        SampleView.as_view(),
        name=&#39;tutorial_view_sample&#39;),

i al views.py
class SampleView(DetailView):
    model = User

Recordau l&#39;error del que hem parlat abans? Doncs el que farem és 
modificar el model per definir el get_absolute_url, també podíem 
haver definitsuccess_urlo sobreescritget_success_url` però això 
ja ho vàrem veure, així que variarem un poc.
Modificam el nostre model 
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return (&#39;tutorial_view_sample&#39;, [self.id, ])

També podíem haver fet el mateix fent servir l&#39;slug, amb la qual cosa 
tindríem urls més amigables. Per això hem de canviar tant la url com 
el get_absolute_url
class Sample(models.Model):
    &quot;&quot;&quot;this is just a sample model&quot;&quot;&quot;

    slug = models.SlugField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    ammount = models.IntegerField()
    comments = models.TextField(blank=True, null=True)

    class Meta:
        verbose_name = &#39;Sample&#39;
        verbose_name_plural = &#39;Sample&#39;

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return (&#39;tutorial_view_sample&#39;, [self.slug, ])

i la url:
url(r&#39;^tutorial/sample/retrieve/(?P&lt;slug&gt;[-\w]+)/$&#39;, 
    SampleView.as_view(),
    name=&#39;tutorial_view_sample&#39;),

Què fa el permalink? doncs, com veis, crea una url per al nostre 
objecte a partir del nom que li hem donat a la url que serveix per 
visualitzar-ho.
Això ens permet no anar posant les urls a foc, sinó tenir-les 
definides amb un nom dins tota l&#39;aplicació.
Si ara provau de fer anar el formulari veureu que ja funciona. Podem 
crear-lo i en guardar mostrar el resulta. Ja tenim dues de les quatre 
lletres, anem a veure les que falten.
Actualització
L&#39;actualització és també molt senzilla. Farem servir UpdateView 
però a diferència de la creació a la url li hem de passar bé la 
clau primària de l&#39;objecte o bé l&#39;slug (sempres suposant que aquest 
sigui únic).
la url:
url(r&#39;^tutorial/sample/update/(?P&lt;slug&gt;[-\w]+)/$&#39;, 
    SampleUpdateView.as_view(),
    name=&#39;tutorial_update_sample&#39;),

pràcticament semblant a la de visualització, i ara a la part de la 
vista bastarà fer:
from django.views.generic.edit import UpdateView

class SampleUpdateView(UpdateView):
    model = Sample

Ara sols ens falta lligar la url per poder anar a l&#39;edició de 
l&#39;objecte, ho podem fer directament des de la barra de navegació, 
però millor posar-ho també a la plana web, per exemple amb un link a 
la plantilla de visualització per a que ens dugui a l&#39;edició de 
l&#39;objecete. Ja que hi sóm posarem també el link de creació. Molt 
resumidament, el nostre sample_detail.html quedaria de la forma:
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Detail&lt;/h1&gt;
    {{sample.slug}}&lt;br/&gt;
    {{sample.name}}&lt;br/&gt;
    {{sample.ammount}}&lt;br/&gt;
    {{sample.comments}}&lt;br/&gt;

    &lt;a href=&quot;{% url tutorial_update_sample sample.slug %}&quot;&gt;Update&lt;/a&gt;|
    &lt;a href=&quot;{% url tutorial_create_sample %}&quot;&gt;Create&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;

Eliminació
Ja hem arribat a la darrera lletra de l&#39;acrònim. Per a esborrar un 
objecte Django ens proporciona la vista DeleteView. Abans d&#39;esborrar 
es convenient demanar confirmació i a la implementació de Django es 
té això en compte.
La url serà de la forma:
url(r&#39;^tutorial/sample/delete/(?P&lt;slug&gt;[-\w]+)/$&#39;,
    SampleDeleteView.as_view(),
    name=&#39;tutorial_delete_sample&#39;),

i a la view.py
from django.views.generic.edit import DeleteView

class SampleDeleteView(DeleteView):
    model = Sample

si volem que tot funcioni per defecte, hem de crear una plantilla 
construida amb el nom del model i el sufixe &quot;_confirm_delete&quot;.
En aquesta plantilla hem de demanar la confirmitat per esborrar el 
registre, enviant-ho a la mateixa URL d&#39;esborrat però fent un POST. 
És a dir la url amb GET presenta la confirmació i amb POST fa l&#39;acció.
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; 
    &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Sample Delete&lt;/h1&gt;
    {{sample.slug}}&lt;br/&gt;
    {{sample.name}}&lt;br/&gt;
    {{sample.ammount}}&lt;br/&gt;
    {{sample.comments}}&lt;br/&gt;

    &lt;p&gt;Are you sure?&lt;/p&gt;

    &lt;form action=&quot;.&quot;
            method=&quot;post&quot; accept-charset=&quot;utf-8&quot;&gt;
            {% csrf_token %}
        &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Delete &amp;rarr;&quot;&gt;&lt;/p&gt;
    &lt;/form&gt;

    &lt;p&gt;&lt;a href=&quot;&lt;a href=&quot;{% url tutorial_view_sample sample.slug %}&quot;&gt;Return&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;

A l&#39;actualització o a la creació no feia falta dir-li a Django on 
volíem anar, per defecte anava a la visualització de l&#39;objecte. Ara 
l&#39;estam esborrant, així que no hi ha objecte. Així que 
obligatòriament li hem de donar la url a la que ha d&#39;anar en cas que 
l&#39;objecte s&#39;hagi eliminat. Ho podem enviar a una plana amb el llistad 
de tots els registres, però com que encara no hem vist com es fa, ara 
per ara l&#39;enviarem al formulari de creació.
class SampleDeleteView(DeleteView):
    model = Sample
    success_url = reverse_lazy(&#39;tutorial_create_sample&#39;)

I ja tenim el CRUD complet. Ens falta poder visualitzar un llistat 
paginat d&#39;objectes i fer algunes accions bàsiques amb formularis. Ho 
veurem al proper apunt.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (IV)</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/21/django-class-based-views-iv/</link>
	<guid>http://trespams.com/2012/02/21/django-class-based-views-iv/</guid>
	<pubDate>mar, 21 Feb 2012 00:00:00 +0100</pubDate>
	<description>Començam a lligar les class views amb els models de dades, que això 
es posa cada cop més interessant.
Fins ara hem vist un ús de les class views molt genèric, és a dir, 
amb el que sabem podem mostrar planes webs i gestionar el treball amb 
formularis.
Es comú en la majoria d&#39;aplicacions web modernes que les dades venguin 
d&#39;algún lloc, d&#39;una base de dades per exemple. Així que la gent de 
Django han creat tota una sèrie de mixin i vistes específices per a 
simplificar-ne el treball.
Mostrar un objecte
Suposem que volem mostrar les dades que tenim d&#39;un usuari. Com sabeu 
el model User de Django conté les dades dels usuaris i es troba a 
django.contrib.auth.models.
Voldríem que en especificar-ne la clau primària a la url poder 
mostrar les dades de l&#39;usuari corresponent.
És a dir, es tracta de mostrar informació que es correspon a urls 
d&#39;aquest tipus
&#39;^prefix/(?P&lt;pk&gt;\d+)/$&#39;

o també 
&#39;^prefix/(?P&lt;slug&gt;[-w]+)/$&#39;

Django ens proporciona la classe DetailView per fer precisament 
això. És a dir, per estalviar-nos la major part de la feina de cercar 
l&#39;objecte que es correspon amb la clau primària o l&#39;slug i passar-ho a 
la plantilla per a la seva presentació. Per si us ho demanaveu 
DetailView es troba a django.views.generic.detail.
Anem a veure un poc DetailView per dintre: 
Aquesta classe hereta de SingelObjectTemplateResponseMixin i de 
BaseDetailView. La primera a la seva vegada és fila de una vella 
coneguda TemplateResponseMixin i en sobrescriu el mètode 
get_template_names per tal d&#39;establir un nom de plantilla per 
defecte, que en el cas dels models és de la forma app/nom_detail.html, 
és a dir, per al nostre exemple, si no posam cap nom de plantilla 
agafarà per defecte auth/user_detail.html.
Per la seva banda BaseDetailView és filla de SingleObjectMixin i de 
View i implementa el mètode get i li passa al contexte de la 
plantilla la variable object amb el contingut de l&#39;objecte que es 
correspon a la clau primària.
Com que object pot resultar un tant confús, Django també passa el 
mateix contingut a una variable amb el nom de l&#39;objecte si el model té 
el nom posat al verbose_name o bé farà servir el que li indiquem a 
l&#39;atribut context_object_name de la Classe.
SingleObjectMixin és la classe encarregada de fer el gruix de la 
feina, i com no, també implementa el mètode get_context_data per a 
poder passar més informació a la plantilla.
Així doncs, mostrar un objecte pot ser tan senzill com això:
al urls.py afegim:
url(r&#39;^user/(?P&lt;pk&gt;\d+)/$&#39;, UserView.as_view(),
        name=&#39;main_user&#39;),

i no oblidem importar UserView, que crearem dins views.py i que pot 
ser tan simple com:
class UserView(DetailView):
    model = User

Com que User té assignat un verbose_name=&#39;User&#39; Django passa a la plantilla 
tant la variable object com la variable user i per tant en 
condicions normals podríem fer servir tant un nom com l&#39;altra. 
En el nostre cas, i si com jo teniu dins el context processors la 
línia &#39;django.contrib.auth.context_processors.auth&#39; us trobareu que la 
variable &quot;no funciona&quot;. Això és perquè encara que se li passi, el 
context processor crea també una variable anomenada &#39;user&#39; amb les 
dades de l&#39;usuari autenticat (si existeix), i com s&#39;assigna just abans 
de generar la plantilla, el contingut que prevaleix és el del context 
processor.
Una cosa que em va sorprendre del SignleObjectMixin és que a més del 
mètode get_object implementa també get_queryset. De fet 
get_objectcrida a get_queryset i li aplica un filtre per clau 
primaria (pk) o bé per slug.
Què vol dir això, doncs que tenim un nivell extra de flexibilitat a 
l&#39;hora de determinar si un objecte és presentable per pantalla o no. 
Basta sobreescriure el mètode get_queryset i independentment que la 
clau primària (o l&#39;slug) existeixi en la base de dades, podem fer que 
l&#39;objecte no es mostri. Per exemple, suposem que en el nostre exemple 
anterior no volem mostrar l&#39;usuari admin.
Podem fer
class UserView(DetailView):
    model = User

    def get_queryset(self):
        query = super(UserView, self).get_queryset()
        return query.exclude(username=&#39;admin&#39;)

de manera que UserView ens mostrarà la informació de qualsevol usuari 
llevat de l&#39;usuari admin, en aquest cas mostrarà un error 404.
SingleObjectMixin com hem dit, pot tornar-nos un objecte a partir de 
la seva clau primària o bé a partir de l&#39;slug. Normalment en farem 
servir un o altre. L&#39;ordre de prioritat és primer el pk i si aquest 
està buid, es mirar l&#39;slug.
Al proper post farem una ullada a les facilitats que ens donen les 
generic class views per a gestionar els manteniments i veurem com es 
pot fer un cicle CRUD.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (III)</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/20/django-class-based-views-iii/</link>
	<guid>http://trespams.com/2012/02/20/django-class-based-views-iii/</guid>
	<pubDate>lun, 20 Feb 2012 00:00:00 +0100</pubDate>
	<description>En aquest apunt veurem com fer servir les generic class views per a 
fer feina amb formularis.
Seguirem la documentació de Django que tracta dels formularis. Allà 
ens fa referència a un formulari de contacte creat com:
from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

i la vista associada
def contact(request):
    if request.method == &#39;POST&#39;: # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect(&#39;/thanks/&#39;) # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response(&#39;contact.html&#39;, {
        &#39;form&#39;: form,
    })

El que farem ara és fer el mateix però fent servir les generic class 
views.
El primer que hem de veure és què hem de fer servir. Necessitam 
gestionar un formulari, la seva validació i tornar la redirecció cap 
a una nova plana web en cas que tot vagi bé.
Si feim una ullada a la jerarquia de classes del mòdul edit podem 
veure que la classes que compleix tot el que volem es diu FormView.
FormView està composada pel mixin TemplateResponseMixin que ja 
coneixem i BaseFormView que a la seva vegada està format per dos 
mixins més FormMixin i ProcessFormView.
FormMixin ens proporciona els mètodes per a gestionar el form i 
ProcessFormView que descendeix de View ens proporciona les respostes 
a les cridades get, post i put.
L&#39;equivalent fent servir les generic class views ens queda:
class ContactView(FormView):
    form_class=ContactForm
    success_url = reverse_lazy(&#39;main_thanks&#39;)
    template_name = &#39;main/index.html&#39;

    def form_valid(self, form):
        # process data
        print form.cleaned_data
        return super(ContactView, self).form_valid(form)

és a dir, hem de dir li a la classe quin formulari farem servir, això 
ho feim a form_class o bé amb la rescriptura del mètode 
get_form_class que ens ha proporcionat el mixin FormMixin o fin i 
tot instanciant el formulari directament si fem la rescriptura de 
get_form
Els mètodes form_valid i form_invalid ens permeten definir què em 
de fer amb el formulari. Normalment ens bastarà sobreescriure el 
mètode form_valid per a adaptar-lo a les nostres necessitats.
I qui crida al mètode is_valid del formulari? Doncs el post que 
prové de ProcessFormView. Recordem que un mixin té accés a tot 
l&#39;objecte que el fa servir, i per tant també té accés als mètodes 
el mixin FormMixin.
Suposem ara que volem que el nostre formulari agafi uns certs valors 
inicials, això ho podem fer amb l&#39;atribut initial definit a 
FormMixin o bé a partir de la reescriptura del mètode 
get_initial, segons la nostra aplicació ens convindrà un mètode o 
un altre.
class ContactView(FormView):
    form_class=ContactForm
    success_url = reverse_lazy(&#39;main_thanks&#39;)
    template_name = &#39;main/index.html&#39;
    initial = {&#39;subject&#39;: u&#39;This is a test form&#39;}

    def form_valid(self, form):
        # process data
        print form.cleaned_data
        return super(ContactView, self).form_valid(form)

Si a més hem de passar dades addicionals a la plantilla Django, 
FormMixin ens proporciona un altre vell conegut, el mètode 
get_context_data que fa el mateix que feia al TemplateView. Això 
sí, ara hem de tenir cura de cridar al mètode pare, ja que als kwargs 
hi ha la definició del formulari. Per a evitar-nos conèixer què fa i 
que no fa, millor cridar al mètode pare i a partir d&#39;aquí afegir-hi 
les variables que necessitem:
class ContactView(FormView):
    form_class=ContactForm
    success_url = reverse_lazy(&#39;main_thanks&#39;)
    template_name = &#39;main/index.html&#39;
    initial = {&#39;subject&#39;: u&#39;This is a test form&#39;}

    def form_valid(self, form):
        # process data
        print form.cleaned_data
        return super(ContactView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(ContactView, self).get_context_data(**kwargs)
        context[&#39;msg&#39;] = u&#39;Hello World&#39;
        return context

I no hem de perdre de vista que estam fent feina amb classes. Podem 
anar afegint els mètodes que necessitem a la classe, de manera que 
cada funció ens quedi manejable.
I ja per acabar un petit avís, he fet servir reverse_lazy per a 
obtenir el valor de la url, però aquesta funció no hi és a Django 
1.3. Per utilitzar el nom de la url enlloc de la url en sí, en Django 
1.3 o bé hem de sobreescriure get_success_url o bé utilitzar 
l&#39;snippet que apareix a Django 
Snippets i que resol això d&#39;una manera 
molt elegant:
from django.utils.functional import lazy
from django.core.urlresolvers import reverse
reverse_lazy = lambda name=None, *args : lazy(reverse, str)(name, args=args)

Això encara dóna per més, fins al proper article!

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (II)</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/20/django-class-based-views-ii/</link>
	<guid>http://trespams.com/2012/02/20/django-class-based-views-ii/</guid>
	<pubDate>dom, 19 Feb 2012 00:00:00 +0100</pubDate>
	<description>En aquesta segona part veurem alguns dels usos més interessants de les 
class based views per a presentar informació i estalviar-nos feina.
TemplateView
Com ja vàrem veure a la primera part el TemplateView ens estalvia 
molta feina respecte a la manera tradicional de fer les coses, sols 
pel fet de passar ja el RequestContext ja recomanaria passar-nos al 
nou món de les Class Based Views, però encara hi ha més!
TemplateView incorpora dos mètodes més get_context_data i get. 
Amb el get el que fa es cridar al mètode render_to_response que 
ens proporciona el mixin TemplateResponseMixin i passant-li com a 
arguments el diccionari que ens ha de tornar el mètode 
get_context_data.
Per defecte get_context_data ens retorna un diccionari amb els 
paràmetres que venen de la url, així si la nostra url és
 url(r&#39;^test3/(?P&lt;id&gt;\d+)/$&#39;, Test3View.as_view(), 
    name=&quot;test3-class-view&quot;),

llavors get_context_data conté el diccionari {&#39;id&#39;: 3} i a la 
plantilla es passarà una variable anomenada params amb aquest 
diccionari.
Suposem però que no és això exactament el que volem. Volem que passi 
a la plantilla una variable anomenanda msg amb una salutació per als 
lectors del blog.
El que farem serà sobreescriure get_context_data per a que passi la 
informació que nosaltres volem a la plantilla.
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = u&#39;Hello blog!&#39;
        return context

Estrictament parlant no faria falta cridar al mètode pare de 
get_context_data i de fet estam passant també la variable params 
però fer-ho no fa mal i ens proporciona un cert grau de protecció 
davant possibles problemes si un dia decidim que Test3View ja no 
heretarà de TemplateView sinó d&#39;una altra classe on ja s&#39;hi posi 
altra informació al contexte.
Al context_data i podem posar tota la informació que necessitem, 
fixem-nos que és el mateix que feiem amb les funcions que acabaven 
cridant al render_to_template sols que ara tot està més estructurat.
Suposem que volem que els missatge no estigui prefixat sinó que es 
generi a partir del resultat d&#39;una funció. Abans hauríem creat la 
funció en algun lloc, a un mòdul apart, abans del mètode que 
renderitza la plantilla, ... Ara ho podem encapsular dins la mateixa 
classe
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_message(self):
        return u&#39;Hello blog&#39;

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context = dict()
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = self.get_message()
        return context

I encara tenim més flexibilitat, gràcies al mixin 
TemplateResponseMixin podem definir quina plantilla s&#39;utilitzarà 
segons ens convingui
Suposem que el paràmetre id ens serveix per a definir el nom de la 
plantilla, de manera que si existeix una plantilla que hi casi la 
presentarà i si no es quedarà amb la plantilla per defecte. Podríem 
fer 
class Test3View(TemplateView):
    template_name = &#39;main/index.html&#39;

    def get_message(self):
        return u&#39;Hello blog&#39;

    def get_template_names(self):
        plantilla = &#39;main/index%s.html&#39; % self.kwargs.get(&#39;id&#39;)
        return [plantilla, ] + super(Test3View, self).get_template_names()

    def get_context_data(self, **kwargs):
        context = super(Test3View, self).get_context_data(**kwargs)
        context[&#39;id&#39;] = self.kwargs.get(&#39;id&#39;)
        context[&#39;msg&#39;] = self.get_message()
        return context

Com veis la potència i la flexibilitat del que es pot fer amb les 
class based views no té res a veure amb el que es podia fer abans. Ara 
tenim molta més flexibilitat, més encapsulació i menys codi a escriure.
Al propert post parlarem de formularis...

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Django class based views (I)</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/19/django-class-based-views-i/</link>
	<guid>http://trespams.com/2012/02/19/django-class-based-views-i/</guid>
	<pubDate>dom, 19 Feb 2012 00:00:00 +0100</pubDate>
	<description>Class based views
Amb Django 1.3 s&#39;introdueixen les &quot;Class based views&quot;, una 
funcionalitat que ens permet modelar les nostres vistes com a classes i que a més 
intenta solucionar el no tenir que escriure sempre el mateix tipus de 
codi quan mostram una plana web o fem un manteniment lligat a un model 
de dades.
Les class based views ens permeten un nivell més alt de reutilització 
del nostre codi i a més ens permeten de mantenir-ne la cohesió. Fins 
ara o bé teníem que anar creant les funcions dins la mateixa vista, 
dins la mateixa funció o tirar de mòduls independents.
Amb les class based views pode anar creant funcions per a la nostra 
vista, de manera que després sigui més bo de fer reaprofitar-les 
extenent la classe.
En poques paraules, les class based views requereixen un temps 
d&#39;adaptació i alguns diuen que aprendre un nou DSL (Domain Specific 
Language). Potser sí, però s&#39;ho paga.
Abans de començar
Encara que podem utilitzar les nostres pròpies class based views, 
Django ens dóna ja fetes les més freqüents i un conjunt de classes 
que podem fer servir en cas que cap ens encaixi.
És en aquestes classes on hi ha gran part de la potència de les class 
based views. Per a fer-les servir hem d&#39;entendre el concepte de Mixin, 
ja que això són aquestes classes: Python mixins.
Què és un mixin?
Un mixin no és res més que una classe que no està concebuda per 
tenir entitat per sí mateixa, sinó per extendra la funcionalitat 
d&#39;altres classes fent servir l&#39;herència múltiple de Python.
Un mixin, per tant, afegeix funcionalitat a les classes. Podem crear 
Mixins com si de mòduls Python es tractàs i aplicar-los a les nostres 
classes per dotar-les de més funcionalitat.
Hem d&#39;entendre també com funciona l&#39;herència múltiple en Python, de 
manera resumida: s&#39;executarà el primer mètode que es trobi anant 
d&#39;esquerra cap a dreta en la definició de les classes. És a dir, si 
tenim:
class Test(OneMixin, AnotherMixin):
    pass

a l&#39;hora d&#39;executar un mètode, Python primer cercarà a OneMixin i si 
no ho troba anirà a AnotherMixin. Així doncs, al tanto que l&#39;ordre en 
que posam les classes és important.
A diferència dels mòduls els mixins tenen accés a la instància 
self de la clases, i per tant poden fer servir informació associada 
a l&#39;objecte i altres mètodes.
La classe View
Aquesta classe és el bessó de tot el muntatge, i si cap de les 
funcionalitats que ens proporciona Django ens serveix gairebé segur 
que començarem a crear la nostra pròpia extenent aquesta classe.
Anem a fer un exemple molt senzill, suposem que volem mostrar una 
plana web, que anomenarem index.html i que posaré dins la carpeta 
main. Com que començam amb això de les generic class views, anam 
llegit i ens n&#39;adonam que la classe View el que fa és capturar els 
noms dels mètodes http i executar-ne una funció associada amb el 
matix nom.
Ja està, ens deim, el que hem de fer es crear una classe que hereti de 
View i escriure&#39;n un mètode que respongui a la creidada GET i que ens 
renderitzi la plana. Dit i fet, cream l&#39;aplicació main i la 
registram al settins.py i anam per feina:
Al mòdul views.py
from django.shortcuts import render_to_response
from django.views.generic.base import View
from django.template import RequestContext

class TestView(View):
    def get(self, request, *args, **kwargs):
        return render_to_response(&#39;main/index.html&#39;, {},
            context_instance=RequestContext(self.request) )

i a urls.py de l&#39;aplicació main
from django.conf.urls.defaults import *
from views import TestView

urlpatterns = patterns(&#39;&#39;,
    url(r&#39;^test2/$&#39;, TestView.as_view(), name=&quot;test-class-view&quot;),
    )

Executam i efectivament això funciona. Ens mostra la plana. Però la 
cosa no ens acaba de convèncer, no?, ja que si fem una ullada a la 
manera anterior de fer les coses, això ben bé es podria fer com:
from django.shortcuts import render_to_response
from django.template import RequestContext

def test(request):
    return render_to_response(&#39;main/index.html&#39;, {},
        context_instance=RequestContext(request) )

hem escrit fins i tot més, on està el guany, doncs? La resposta està 
en la reusabilitat.
Aquest patró de mostrar planes web senzilles es repeteix molt en les 
aplicacions web, de manera que la gent de Django ja ha creat una 
classe que hereta de Views i que fa precissament això i d&#39;una manera 
més genèrica, la classe TemplateView
Aquesta classe hereta de TemplateResponseMixin i de View. 
TemplateResponseMixin és un mixin que té dos mètodes: 
render_to_response i get_templates_names i dos atributs: 
template_name i response_class. El que ens interessa ara és que 
TemplateResponseMixin ens permet afegir a la nostra classe la 
renderització de la plantilla que passem dins template_name o bé 
que tornem a partir de la sobreescriptura de get_templates_names
Si fem servir TemplateView el nostre codi queda com:
from django.views.generic.base import TemplateView

class IndexView(TemplateView):
    template_name = &#39;main/index.html&#39;

i a urls.py
from django.conf.urls.defaults import *
from views import IndexView

urlpatterns = patterns(&#39;&#39;,
    url(r&#39;^$&#39;, IndexView.as_view(), name=&#39;main_index&#39;),
    )

Fins i tot podríem prescindir del codi de view.py i podríem fer:
from django.conf.urls.defaults import *
from django.views.generic.base import TemplateView

urlpatterns = patterns(&#39;&#39;,
    url(r&#39;^$&#39;, IndexView.as_view(template_name=&#39;main/index.html&#39;), 
        name=&#39;main_index&#39;),
    )

Com podeu veure l&#39;estalvi en línies de codi comença a ser notable.
L&#39;important, a més de veure com es pot extendre la funcionalitat de 
Views és que vegem què senzill és separar la funcionalitat lligada 
al GET de la funcionalitat lligada al POST, al PUT, o a qualsevol 
cridada HTTP. Sols hem de crear una funció amb aquest nom i Django la 
cridarà sempre que la nostra classe hereti de View.
Suposem doncs que el que volem ara és mostrar una plana diferent si 
algú ens intenta fer un POST contra la nostra plana. Django té un 
mecanisme per protegir-nos d&#39;això és el CSRF o Cross Site Request 
Forgery 
protection, 
ara el que voldriem es desactivar aquest mecanisme per la nostra 
classe i mostrar una plana diferent d&#39;avís.
Amb el mètode classis hauríem de fer un 
if request.method==&#39;POST&#39;:
    #fes alguna cosa
else:
    #fes una altra cosa

amb les Class Based Views la cosa queda molt més elegant:
class TestView(View):
    def get(self, request, *args, **kwargs):
        return render_to_response(&#39;main/index.html&#39;, {},
            context_instance=RequestContext(self.request) )

    def post(self, request, *args, **kwargs):
        return render_to_response(&#39;no_post_allowed.html&#39;)

Això tal com està no funcionaria, ja que tenim pel mig la protecció 
de Django.
Per saltar-nos aquesta protecció li hem de dir a la vista que no la 
volem i per fer-ho hem de sobreescriure el mètode dispatch que  se
n&#39;encarrega de la fontaneria de verificar quin mètode http 
ens ve i la funció que hem de cridar.
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class TestView(View): 
    def get(self, request, *args, **kwargs):
        return render_to_response(&#39;main/index.html&#39;, {},
            context_instance=RequestContext(self.request) )

    def post(self, request, *args, **kwargs):
        return render_to_response(&#39;no_post_allowed.html&#39;)

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(TestView, self).dispatch(*args, **kwargs)

Hem vist fins ara com fer servir la classe View i la classe 
TemplateView, hi tornarem en els propers apunts, estau atents.        

3 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Una simple e imposible consulta en django</title>
	<author>Yaco</author>
	<link>http://www.yaco.es/blog/django/2012/02/a-simple-and-impossible-query-in-django/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-simple-and-impossible-query-in-django</link>
	<guid>http://www.yaco.es/blog/django/2012/02/a-simple-and-impossible-query-in-django/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-simple-and-impossible-query-in-django</guid>
	<pubDate>lun, 13 Feb 2012 00:00:00 +0100</pubDate>
	<description>El ORM junto a los formularios, según mi opinión, son las partes más potentes y destacables que tiene Django. Ambos componentes hacen que trabajar con este framework sea más liviano. Pero dicho esto, obviamente, no quiere decir que estén completos o que no contengan errores. En este artículo voy a proponer dos nuevos</description>
	</item>

	<item>
	<title>Una simple e imposible consulta en django</title>
	<author>Yaco</author>
	<link>http://www.yaco.es/blog/contribuciones/2012/02/a-simple-and-impossible-query-in-django/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-simple-and-impossible-query-in-django</link>
	<guid>http://www.yaco.es/blog/contribuciones/2012/02/a-simple-and-impossible-query-in-django/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-simple-and-impossible-query-in-django</guid>
	<pubDate>lun, 13 Feb 2012 00:00:00 +0100</pubDate>
	<description>El ORM junto a los formularios, según mi opinión, son las partes más potentes y destacables que tiene Django. Ambos componentes hacen que trabajar con este framework sea más liviano. Pero dicho esto, obviamente, no quiere decir que estén completos o que no contengan errores. En este artículo voy a proponer dos nuevos</description>
	</item>

	<item>
	<title>Dajaxaproject, segona part</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/02/12/djaxaproject-segona-part/</link>
	<guid>http://trespams.com/2012/02/12/djaxaproject-segona-part/</guid>
	<pubDate>dom, 12 Feb 2012 00:00:00 +0100</pubDate>
	<description>Abans d&#39;escriure aquest apunt de m&#39;he adonat que era el post amb 
l&#39;identificador 500. Un nombre rodó i que potser mereixeria algun 
tipus de celebració, però tanmateix no és l&#39;apunt que fa 500, ja que 
en les proves del codi del blog, segurament vaig afegir i esborrar 
apunts que han fet anar cap endavant el comptador, realment encara 
falten prop d&#39;una trentena d&#39;apunts per a arribar al que fa 500, així 
que deixaré el cava a la gelera.
Hi va haver una proposta de celebrar-ho fent un regal, però pareix que 
la meva proposta de regalar una capsa d&#39;un Nexus (tot i que comptava 
amb un possible patrocionador) no ha arribat a cuallar :-P
Així doncs el que faré és reprende l&#39;apunt sobre el dajaxproject, i 
em centraré en l&#39;altra component, anomenat Dajax.
Dajax
Ja vàrem veure com dajaxice ens deixava fer cridades AJAX cap a la nostra 
aplicació Django i organitzar-les. Dajax va més enllà in ens permet 
interactuar amb la interfície d&#39;usuari des de codi Python. Fet servir 
amb mesura i seny ens pot ajudar també a fer molt més legible el 
nostre codi i a organtizar millor les accions derivades d&#39;una cridada 
AJAX dins el mateix codi que les gestiona. No us penseu però que es 
tracta de quelcom com Pyjamas sinó que són més 
bé un conjunt de primitives que ens permetran agilitar la feina.
Per començar a jugar-hi necessitareu haver llegit el meu apunt 
anterior (o la documentació del projecte) ja que Dajax fa servir la 
seva llibreria germana dajaxice i també tenir instal·lat algun dels 
frameworks javascript suportats, en el meu cas faré servir jQuery.
Recepta
A la part de servidor

Instal·lau django-dajax i posau dajax com a aplicació al 
settings.py.


Posau from dajax.core.Dajax import Dajax a l&#39;arxiu ajax.py de la 
vostra aplicació, junt amb from dajaxice.decorators import 
dajaxice_register que ja havíem vist abans per a registrar la petició.


A la funció AJAX instanciarem la classe, dajax=Dajax()


Farem el que tinguem que fer dins la funció AJAX i després anirem 
executant els mètodes de dajax que ens interessin per a 
interaccionar amb la part HTML de l&#39;aplicació.


Finalment retornarem el json amb return dajax.json()

A la part de client
Hem de afegir l&#39;arxiu javascript que correspongui segons la llibreria 
que volguem fer servir. En el nostre cas jquery.dajax.core.js que es 
troba a django-dajax/scr/. En el meu cas la cosa queda com:
{% dajaxice_js_import %}
&lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;{{STATIC_URL}}/jquery.dajax.core.js&quot;&gt;&lt;/script&gt;

En executar-se l&#39;event que ens interessi (un clic normalment) cridarem 
la función AJAX que hem registrat de manera semblant a com ho feiem a 
l&#39;exemple de Dajaxice, però ara a la funció li passarem com a 
paràmetre Dajax.process i un diccionari java de valors opcional, si 
la funció té paràmetres.
Important Un ús molt habitual de Dajax es dona en combinació amb 
els formularis Django, en aquest cas el paràmetre de les dades del 
formulari. Per a que Django les pugui interpretar bé com a provinents 
d&#39;un formulari hem de serialitzar-les, si fem servir jQuery això 
necessita d&#39;una llibreria addicional anomenada 
serializeobject.
Què es pot fer?
Les funcions que ens proporciona Dajax ens permeten tant manipular 
l&#39;arbre DOM de la plana web com cridar a funcions javascript ja que 
tinguem fetes.
*alert(message) Com el seu nou indica hi haureu endivinat, 
    mostra una alterta javascript amb el missatge que li indiquem.

assign(selector, attribute, valor) Donat un selector (id, 
    classe, tipus, ...) i un atribut li asigna el valor el valor que 
    li passam al paràmetre a tots els elements que casin amb el 
    selector. Seria l&#39;equivalent a fer amb jQuery per 
    exemple $(&#39;.test&#39;).attr(&#39;title&#39;, &#39;hola&#39;) però enlloc de 
    aplicar-ho sols al primer element com fa jQuery ho aplicaria a 
    tots els elements que tinguin assignada la classe test.


add_css_class(selector,value). Assigna tots els elements que 
    casin amb el selector la classe css especificada a paràmetre 
    value. value pot ser una cadena o bé una llista de cadenes, en 
    cas de ser una llista s&#39;assignaran totes les classes de la llista.


remove_css_class(selector,value). Funció complementaria de 
    l&#39;anterior, és a dir, enlloc de posar lleva.


append(selector,attribute,value)afegeix a tots els elements 
    que casin amb el seletor l&#39;atribut donat amb el valor indicat avalue`.


prepend(selector,attribute,value) Afegeix a l&#39;inici a tots els elements 
    que casin amb el selector l&#39;atribut especificat amb el valor que 
    li passam com a paràmetre.


clear(selector,attribute). Netja l&#39;atribut especificat de tots 
    els elements que casin amb el selector.


redirect(url,delay=0). Redirecciona la plana cap la nova url 
    després del temps especificat en el paràmetre delay.


script(code). Executa el codi javascript especificat en el 
    navegador. Per exemple, podem executar l&#39;alert de l&#39;exemple 
    anterior. Hem d&#39;anar un poc alerta amb aquesta funció i evitar 
    fer-ne un mal ús posant-hi tot el codi. Si hem de fer crides, 
    millor posar-les dins el seu corresponent arxiu javascript i fer 
    tan sols script(la_funcio()).


remove(selector). Elimina tots els elements que casen amb el 
    selector especificat.


add_data(data,callback_function). Executa la funció que li 
    especificam en el segon paràmetre amb les dades que hem posat al 
    primer paràmetre. Com el cas d&#39;script alerta amb abusar-ne.

Algunes recomanacions
Django té un sistema de plantilles molt potent, es poden fer servir 
junt amb assign i remove per a posar els continguts que ens 
interessin. Vull dir que no fa falta que una plantilla estigui lligada 
a un view sinó que es pot fer servir directament. Mirau-ne 
l&#39;API.
Podem generar contingut HTML (o js) directament o fer servir una 
plantilla a un fitxer i utilitzar el render_to_string.
Tampoc estam limitats a fer servir el sistema de plantilles de Django 
per a generar l&#39;HTML segons el que es tengui que tornar potser un 
sistema com Mako us va millor. Personalment sóc partidari de no 
mesclar massa.
Errors típics
Sovint et pots passar una bona estona demanant-te perquè no funciona 
la teva cridada AJAX, així que anem a fer una llista de recomanacions:

Reinicia la consola de desenvolupament. A vegades la nova función 
no es registra bé i no es torna a generar el codi javascript. Si això 
passa, el símptoma és que tens un error dient que no es troba la 
funció.


Hi ha un error que diu que no es troba Dajax al javascript. Típic 
de quan t&#39;has oblidat de incloure la llibreria específica pel 
frameworks que fas servir.


Es fa la cridad però no s&#39;executa res. Doncs que t&#39;has deixat el 
retorn a la funció AJAX. Recorda que normalment hi haurà un return 
dajax.json() o si no les cridades no s&#39;efectuaran.


Django no és capaç d&#39;interpretar el que li enviam al formulari. 
Ens hem deixat la llibreria serializeobject


Teníem events lligats a un element i ara no responen. Típic de 
quan hem generat nou contingut. Els events s&#39;han de tornar a lligar 
amb els nous continguts encara que tenguéssin el mateix identificador. 
Potser fer servir .live() o .delegate() de jQuery ajudaria, però ara 
per ara jo el que he fet és tornar-los a lligar posant els elements a 
una funció d&#39;inicialització i tornar-la a cridar amb script.

2 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Mejora a Logging por default en Django</title>
	<author>DynamicWare</author>
	<link>http://blog.hgdeoro.com.ar/2012/02/mejora-logging-por-default-en-django.html</link>
	<guid>http://blog.hgdeoro.com.ar/2012/02/mejora-logging-por-default-en-django.html</guid>
	<pubDate>mar, 7 Feb 2012 00:00:00 +0100</pubDate>
	<description>La configuración por default de LOGGING de Django hace que no se muestren por consola los mensajes de logging generados, sólo muestra los requests, y hacer que se vean nuestros mensajes es bastante fácil, sólo hay que agregar a LOGGING (en settings.py) las líneas en negritas:LOGGING = {    &#39;version&#39;: 1,    &#39;disable_existing_loggers&#39;: False,    &#39;handlers&#39;: {        &#39;mail_admins&#39;: {            &#39;level&#39;: &#39;ERROR&#39;,            &#39;class&#39;: &#39;django.utils.log.AdminEmailHandler&#39;        },        &#39;console&#39;: {            &#39;level&#39;: &#39;INFO&#39;,            &#39;class&#39;: &#39;logging.StreamHandler&#39;        },    },    &#39;loggers&#39;: {        &#39;&#39;: {            &#39;handlers&#39;: [&#39;console&#39;],            &#39;level&#39;: &#39;INFO&#39;,            &#39;propagate&#39;: True,        },        &#39;django.request&#39;: {            &#39;handlers&#39;: [&#39;mail_admins&#39;],            &#39;level&#39;: &#39;ERROR&#39;,            &#39;propagate&#39;: True,        },    }}(esto funcionará en Django &gt;= 1.3)</description>
	</item>

	<item>
	<title>Configurar logging en python y django con yaml</title>
	<author>Estribancus</author>
	<link>http://www.pvilas.com/2012/02/configurar-logging-en-python-y-django.html</link>
	<guid>http://www.pvilas.com/2012/02/configurar-logging-en-python-y-django.html</guid>
	<pubDate>mar, 7 Feb 2012 00:00:00 +0100</pubDate>
	<description>Os paso el esquema de logging que utilizo en mis aplicaciones por si os puede servir de ayuda. Lo he ido montando a partir de diversas fuentes y experiencias.Un punto importante es dejar el fichero de configuración del logging fuera del programa para independizar mejor el sistema de logging de la aplicación.Este puede ser un ejemplo del fichero de configuración en yaml (logger.conf):version: 1formatters:  brief:    format: &#39;%(name)s - %(levelname)s - %(message)s&#39;  simple:    format: &#39;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#39;  detailed:    format: &#39;%(asctime)s %(module)-17s line:%(lineno)-4d %(levelname)-8s %(message)s&#39;  email:    format: &#39;Timestamp: %(asctime)s\nModule: %(module)s\n Line: %(lineno)d\nMessage: %(message)s&#39;handlers:  console:    class: logging.StreamHandler    level: DEBUG    formatter: brief    stream: ext://sys.stdout  file:    class: logging.handlers.RotatingFileHandler    level: INFO    formatter: detailed    filename: app.log    mode: a    maxBytes: 10485760    backupCount: 5  smtp:    class: logging.handlers.SMTPHandler    level: ERROR    formatter: email    mailhost: smtp.xxxxx.es    fromaddr: yyy@xxxx.es    toaddrs:  yyyy@xxxx.es    subject:  Error en aplicacion XXroot:  level: DEBUG  handlers: [console]Se observan los formateadores de los mensajes y los handlers para la cónsola, fichero y correo. Por defecto el logging sale por cónsola, si queremos que los errores salgan por email handlers de root sería [console, smtp], para fichero que rotara cada maxBytes [file], etc... Realmente cómodo.Para cargar la configuración, primero parseamos el yaml (PyYAML) y luego lo enviamos a dictConfig, que realiza la configuración así:import yamlimport logging#nos aseguramos de que dictConfig esté presente (python 2.7), sino, lo cargamos de la libreria de django try:     from logging.config import dictConfig except ImportError:     from django.utils.dictconfig import dictConfig# Cargamos la configuracion del fichero, la parseamos y la enviamos a dictConftry:    logging.config.dictConfig(yaml.load(file(&#39;logger.conf&#39;,&#39;r&#39;)))except Exception, e:    print &quot;Error configurating logger &quot;, str(e)Ahora ya podemos el usar el sistema. En general, es conveniente nombrar cada logger con el nombre de su módulo para que cuando haya muchos mensajes sepamos cuál los está enviando, para ello podemos usar el valor de __name__, así:logger=logging.getLogger(__name__) # __name__ contiene el nombre del modulologger.debug(&quot;blah blah&quot;)Si queremos que cada clase tenga su logger privado, tenemos que tomar una pequeña precaución para evitar un error si otros usan una librería nuestra con otro sistema de handles,Declaramos una clase &quot;nula&quot;:class Nullhandler(logging.Handler):   def emit(self, record):      passy ahora, en la clase hacemosclass Clase():   def __init__(self):      self.__logger=logging.getLogger(__name__)      self.__logger.addHandler(NullHandler())      self.__logger.debug(&quot;clase iniciada&quot;)Como veis es un tema un poco denso pero que una vez bien configurado nos será imprescindible para trazar correctamente las aplicaciones. Espero que os haya ayudado.</description>
	</item>

	<item>
	<title>Acelerando tests de Django con PostgreSql</title>
	<author>DynamicWare</author>
	<link>http://blog.hgdeoro.com.ar/2012/02/acelerando-tests-de-django-con.html</link>
	<guid>http://blog.hgdeoro.com.ar/2012/02/acelerando-tests-de-django-con.html</guid>
	<pubDate>sáb, 4 Feb 2012 00:00:00 +0100</pubDate>
	<description>La ejecucion inicial de los tests toma aproximadamente 15 segundos:4.54user 0.64system 0:15.25elapsed 34%CPU (0avgtext+0avgdata 123600maxresident)k4.70user 0.54system 0:14.70elapsed 35%CPU (0avgtext+0avgdata 122992maxresident)k4.46user 0.65system 0:14.85elapsed 34%CPU (0avgtext+0avgdata 122912maxresident)kLuego de ajustar los siguientes parametros:- fsync = off- synchronous_commit = off- wal_sync_method = fsyncla ejecución toma aproximadamente 8.5 segundos:4.22user 0.56system 0:08.62elapsed 55%CPU (0avgtext+0avgdata 123024maxresident)k4.32user 0.58system 0:08.97elapsed 54%CPU (0avgtext+0avgdata 123008maxresident)k4.29user 0.50system 0:08.74elapsed 54%CPU (0avgtext+0avgdata 123040maxresident)kEl tiempo se redujo casi a la mitad! Aunque esta configuración no es para nada recomendable para un equipo de producción, creo que vale la pena para ejecutar tests.</description>
	</item>

	<item>
	<title>Corriendo tests con instancia de PostgreSql en ram</title>
	<author>DynamicWare</author>
	<link>http://blog.hgdeoro.com.ar/2012/02/corriendo-tests-con-instancia-de.html</link>
	<guid>http://blog.hgdeoro.com.ar/2012/02/corriendo-tests-con-instancia-de.html</guid>
	<pubDate>sáb, 4 Feb 2012 00:00:00 +0100</pubDate>
	<description>Otra manera de optimizar la ejecución de tests de Django, pero SIN modificar la instalación de PostgreSql del sistema operativo es crear una nueva instancia, corriendo totalmente en ram.Para crear una nueva instancia usamos initdb:$ /usr/lib/postgresql/9.1/bin/initdb \    --pgdata=/dev/shm/pgtesting \    -U horacioY para lanzar la instancia en segundo plano:$ /usr/lib/postgresql/9.1/bin/postgres \    -F -i -p 5444 -S $((1024*64)) \    -D /dev/shm/pgtesting \    --unix_socket_directory=/dev/shm/pgtesting \    -r /dev/shm/pgtesting/postgresql.log &amp;Luego creamos el usuario y BD para la aplicación Django:psql -h 127.0.0.1 \    -c &quot;create user vindler with password &#39;x&#39; superuser&quot; postgrespsql -h 127.0.0.1 \    -c &quot;create database vindler owner vindler&quot; postgresMejora en tiempos de ejecución de test: 28%La ejecución de los tests con PostgreSql en disco, con las optimizaciones de mi artículo anterior tardan alrededor de 7 segundos:Ran 18 tests in 7.071s5.44user 0.58system 0:10.40elapsed 57%CPU (0avgtext+0avgdata 122880maxresident)k0inputs+1184outputs (0major+16964minor)pagefaults 0swapsRan 18 tests in 6.843s5.28user 0.65system 0:10.27elapsed 57%CPU (0avgtext+0avgdata 122976maxresident)k0inputs+1176outputs (0major+16956minor)pagefaults 0swapsRan 18 tests in 7.032s5.42user 0.64system 0:10.42elapsed 58%CPU (0avgtext+0avgdata 124304maxresident)k0inputs+1168outputs (0major+17122minor)pagefaults 0swapsLos mismos tests ejecutandose en la nueva instancia de PostgreSql totalmente en ram, tardan alrededor de 5 segundos:Ran 18 tests in 5.220s4.41user 0.65system 0:08.38elapsed 60%CPU (0avgtext+0avgdata 117904maxresident)k8inputs+1176outputs (0major+16524minor)pagefaults 0swapsRan 18 tests in 5.047s4.32user 0.53system 0:08.04elapsed 60%CPU (0avgtext+0avgdata 117888maxresident)k0inputs+1168outputs (0major+16504minor)pagefaults 0swapsRan 18 tests in 4.665s3.95user 0.64system 0:07.79elapsed 58%CPU (0avgtext+0avgdata 117856maxresident)k0inputs+1176outputs (0major+16502minor)pagefaults 0swapsAl ejecutar los tests de stress: 33%Con PostgreSql en disco:Ran 1 test in 24.601s15.21user 2.72system 0:27.98elapsed 64%CPU (0avgtext+0avgdata 130944maxresident)k0inputs+9616outputs (0major+18298minor)pagefaults 0swapsRan 1 test in 24.458s15.16user 2.51system 0:27.57elapsed 64%CPU (0avgtext+0avgdata 131488maxresident)k472inputs+9608outputs (0major+18457minor)pagefaults 0swapsRan 1 test in 24.552s15.23user 2.63system 0:27.95elapsed 63%CPU (0avgtext+0avgdata 131088maxresident)k232inputs+9616outputs (0major+18310minor)pagefaults 0swapsCon PostgreSql en ram:Ran 1 test in 16.082s11.30user 2.46system 0:19.22elapsed 71%CPU (0avgtext+0avgdata 126080maxresident)k0inputs+9616outputs (0major+17675minor)pagefaults 0swapsRan 1 test in 15.736s11.25user 2.20system 0:18.82elapsed 71%CPU (0avgtext+0avgdata 126192maxresident)k0inputs+9608outputs (0major+17684minor)pagefaults 0swapsRan 1 test in 15.408s10.78user 2.27system 0:18.44elapsed 70%CPU (0avgtext+0avgdata 126384maxresident)k0inputs+9608outputs (0major+17693minor)pagefaults 0swaps</description>
	</item>

	<item>
	<title>Dajaxproject, primera part</title>
	<author>Trespams</author>
	<link>http://trespams.com/2012/01/30/dajaxproject-primera-part/</link>
	<guid>http://trespams.com/2012/01/30/dajaxproject-primera-part/</guid>
	<pubDate>lun, 30 Ene 2012 00:00:00 +0100</pubDate>
	<description>Una de les preguntes més recurrents en les llistes de Django, junt amb 
la de quin editor fer servir és la de com fer cridades AJAX i quina 
llibreria utilitzar.
Django és agnòstic en el que fa a les llibreries javascript, tot i 
això la part de l&#39;admin fa servir jQuery, però oficialment no hi ha 
cap llibreria especialment recomanada, Django és pot utilitzar amb 
qualsevol llibreria i dependrà del projecte que en triem una o altra.
El problema de que no es faci cap recomanació de com integrar cridades 
AJAX amb Django ens dóna molta llibertat, però també te l&#39;emperò de 
que no hi ha cap guia de bones pràctiques sobre com fer-ho, des d&#39;on 
posar la llibreria, quin nom li hem de donar, si la posam al views.py 
o no.
El la comunitat de codi obert quan hi ha un buid així i una necessitat 
ben aviat sorgeixen projectes que intenten donar una resposta. Un 
d&#39;aquests projectes és el que us present en aquest article el 
dajaxproject.
Djaxaproject són de fet dues llibreries, dajaxice i dajax, la primera 
podríem dir que respon a la necessitat que us comentava de fer més 
senzilla la comunicació asíncrona entre les aplicacions Django y el 
codi javascript, la segona, dajax està molt més orientada cap a la 
capa de presentació i sobretot està lligada a un bastiment de 
javascript en concret, encara que tenim certa llibertat a l&#39;hora de 
triar-lo.
En aquest apunt veurem primer Dajaxice i en un següent apunt faré 
també cinc cèntims de dajax.
Instal·lació
Suposaré com tantes vegades que teniu un virtualenv creat i Django 
instal·lat. També hem de partir d&#39;un projecte base.
El primer que hem de fer és instal·lar la llibreria, per això 
bastarà fer un 
pip install django-dajaxice

La documentació explica força bé el 
procés, així que resumeixo:
Posar dajaxice dins la secció INSTALLED_APPS de settings.py
Assegurar-nos que tenim eggs.Loader descomentat als TEMPLATE_LOADERS
Assegurar-nos que django.core.context_processors.request és dins 
el TEMPLATE_CONTEXT_PROCESSORS, si no ho heu fet ja, el meu consell és 
que copieu tot el TEMPLATE_CONTEXT_PROCESSORS que hi ha a la 
documentació, ja que a poc que l&#39;aplicació cresqui segur que 
necessitareu afegir-ne algun.
Afegim als settings.py el prefixe que farem servir per distingir les urls de 
dajaxice de les de urls normals de la nostra aplicació, per exemple la 
documentació ens diu posar DAJAXICE_MEDIA_PREFIX=&quot;dajaxice&quot;.
Amb això ja hem fet par de la fontaneria, ara ve la part més 
interessant i la màgia d&#39;aquesta aplicació.
Organitzant l&#39;AJAX
Dajaxice el farà és utilitzar el prefixe que hem configurat per 
tractar certes urls com a cridades AJAX. Djaxice el que ens permet és 
registrar automàticament les funcions que es publicaran com a cridades 
AJAX utilitzant un mecanisme semblant al que fa dervir Django per a 
l&#39;admin.
D&#39;aquesta manera, una vegada modificat l&#39;arxiu urls.py podem anar 
creant les funcions a publicar dins un arxiu ajax.py i registrar les 
funcions. Així l&#39;arxiu urls.py ens ha de quedar com:
#!/usr/bin/python

from django.conf.urls.defaults import patterns, include, url
from dajaxice.core import dajaxice_autodiscover
from django.contrib import admin
from django.conf import settings

admin.autodiscover()
dajaxice_autodiscover()

urlpatterns = patterns(&#39;&#39;,
     url(r&#39;^admin/&#39;, include(admin.site.urls)),
    (r&#39;^%s/&#39; % settings.DAJAXICE_MEDIA_PREFIX, 
        include(&#39;dajaxice.urls&#39;)),
)

Utilitzant AJAX a les nostres plantilles
Dajaxice es capaç de posar dins la nostra plantilla el codi que 
necessitam per fer les cridades AJAX i publicar les funcions que farem 
servir a partir del codi Python (ja ho veurem un poc més endavant). 
Per fer-ho fa servir una llibreria que s&#39;ha de carregar.
Així a la part de càrrega de llibreries de la nostra plantilla haurem 
d&#39;afegir: dajaxice_templatetags. Si encara no heu carregat cap 
llibreria doncs quedaria com {% load dajaxice_templatetags %}.
Una vegada carregada la llibreria posarem el tag que genera el codi 
javascript {% dajaxice_js_import %}. Ho podeu posar a la capçalera o 
al peu de la plana. Personalment, com que ho sol fer servir junt amb 
jQuery, ho pos al peu, abans de l&#39;utilització  de les llibreries, per tal de millorar la velocitat de càrrega de les planes. 
Aquest codi es gener dinàmicament mentre estam desenvolupant. Us avís 
que de tant en tant es queda carregat en memòria i certs canvis 
requereixen reiniciar el servidor de desenvolupament. Si veis que heu 
publicat una funció i no surt, reiniciau el servidor.
En producció la llibreria té una opció per generar directament 
l&#39;arxiu javascript i poder tractar-lo com un fitxer estàtic més.
L&#39;estructura d&#39;una plantilla bàsica amb djaxice seria doncs
{% load dajaxice_templatetags %}

&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;My base template&lt;/title&gt;
    &lt;!-- també al peu depen de l&#39;aplicació --&gt;
    {% dajaxice_js_import %} 
  &lt;/head&gt;
...
&lt;/html&gt;

Creant la nostra primera cridada AJAX
Com us comentava més amunt, una de la gràcia de dajaxice és que ens 
permet organitzar les nostres cridades AJAX. Així el que farem serà 
crear un arxiu ajax.py dins la nostra aplicació, de manera que podem 
agrupar cridades per aplicació.
Suposem que hem creat una aplicació anomenada main, la posam al 
settings.py del projecte i cream l&#39;arxiu ajax.py
Crear una funció i publicar-la per a que la servim via AJAX és tan 
senzill com això:
#!/usr/bin/python
# -*- coding: utf-8 -*-

from django.utils import simplejson
from dajaxice.decorators import dajaxice_register

@dajaxice_register
def hello_world(request):
    return simplejson.dumps(
        {&#39;message&#39;:&#39;Hello World&#39;})

És a dir, importam simplejson per a fer la transformació cap a json, 
que és el que volem servir (o xml, o html, tant fa), cream una funció 
com ho feim al views.py de Django i la decoram ambdajaxice_register. Això junt el autodiscover que hem posat a 
urls.py fa que ara la nostra aplicació pugui respondre a cridades 
AJAX.
Cridant des de l&#39;html
Per cridar a la nostra funció es pot fer directament amb l&#39;event 
onclick directament a l&#39;HTML,però a mi particularment em fa molta 
grima tenir aquesta mescladissa, així que prefereixo tirar de jQuery 
encara que per fer la crida AJAX no el faci servir. Recordem que 
l&#39;important no és el mètode amb que es fa la crida, sinó 
l&#39;organització i facilitat de mantenimient (i depuració) que ens 
dóna la llibreria.
Així, en el meu cas quedaria:
&lt;script src=&quot;https://ajax.googleapis.com/
    ajax/libs/jquery/1.7.1/jquery.min.js&quot;&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    $(function(){
        $(&#39;#testme&#39;).click(function(event){
            event.preventDefault();
            Dajaxice.main.hello_world(test_callback);
        });

        function test_callback(data){
            if (data==Dajaxice.EXCEPTION){
                alert(&#39;Opps, alguna cosa dolenta ha passat&#39;);
            } else {
                alert(data);
            }
        }
    });
&lt;/script&gt;

on #testme fa referència a un enllaç al qual hem assignat l&#39;event.
L&#39;interesant d&#39;això és que tenim a la nostra disposició una funció 
javascript que mapeja la que tenim al codi Python i a la qual podem 
cridar amb uns paràmetres. El primer d&#39;ells és la funció de tornada 
(el callback) que utilitzarem per gestionar la resposta i l&#39;altra és 
un paràmtre codificat com json que passarà com a paràmetre cap a la 
funció.
Hem de dir que dajaxice sempre fa un POST contra la url, gestionant 
els problemes de CSRF.
Si posam DAJAXICE_DEBUG=True al settings.py o millor dit, ve així 
per defecte, a la consola de desenvolupament de Django podem veure 
tant la cridada que fem com la resposta i els errors que hi pugui 
haver.
La funció de tornada es defineix amb un paràmetre que contindrà el 
valor de retorn de la nostra cridada AJAX. Si és un json podrem 
accedir als valors directament, però com he comentat abans, no estam 
limitats a tornar json, podem tornar una cadena de text, xml, html, 
... el que necessitem i poguem tractar amb javascript.
És interessant veure com es tracten els errors o les excepcions. Si hi 
ha problems al nostre codi Python i es llança una excepció, dajaxice 
la capturarà i llavors data contindrà el valor Dajaxice.EXCEPTION, 
amb la qual cosa sabem que quelcom ha anat malament.
He de fer servir sempre Dajaxice?
Depèn, algunes vegades serà més convenient fer una cridada directa 
amb jQuery, per exemple quan volem tenir més control del que passa 
quan s&#39;inicia la cridada, o volem poder-la cancel·lar. 
El cert, però, és que dajaxice ens permet organitzar millor el codi i 
gestionar d&#39;una manera sistemàtica les nostres cridades AJAX. Com 
sempre no hi ha cap veritat absoluta, potser servirà en el 80% dels 
casos i això ja significa una gran ajuda.

0 comentaris,
0 trackbacks (URL)
Automatic translations of  this post by Apertium</description>
	</item>

	<item>
	<title>Instalando django_openid_auth usando PIP</title>
	<author>DynamicWare</author>
	<link>http://blog.hgdeoro.com.ar/2012/01/instalando-djangoopenidauth-usando-pip.html</link>
	<guid>http://blog.hgdeoro.com.ar/2012/01/instalando-djangoopenidauth-usando-pip.html</guid>
	<pubDate>mié, 25 Ene 2012 00:00:00 +0100</pubDate>
	<description>Hay algunos problemas con la version 0.4 de django_openid_auth (ej: no se puede instalar via pip). El proyecto es open source, por lo tanto es muy facil subirlo a GitHub y compartir estos arreglos :-)Básicamente bajé el proyecto original (revisión 88) y lo subi a GitHub. Para instalarlo usando PIP hay que ejecutar:./pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth#egg=django_openid_authActualizaciónMucho mejor, instalamos usando PIP, pero un commit en particular (ec68dfc046d1a75b50080ea98c56eda71956ed7a):pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth@ec68dfc046d1a75b50080ea98c56eda71956ed7a#egg=django_openid_authO también un tag en particular (bzr_revno_88):pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth@bzr_revno_88#egg=django_openid_auth</description>
	</item>

</channel>
</rss>

