Filtres a l'admin de Django 1.4
Escrit per Aaloy a 31 de July , 2012 a les 9:42 p.m.
En una de les darreres aplicacions que hem fet, la d'apibaleares hem tirat força de l'administrador de Django. Segurament i donades les característiques que volem que tengui l'apliació al final, anirem cap a un administrador ad-hoc, però ara per començar va força bé.
Un dels primers problemes va sorgir amb els filtres. Amb l'admin de Django és molt senzill fer un filtre per qualsevol camp, però té l'emperò que si el camp és una clau forana cap a una altra taula amb molts elements Django et pinta tots els elements, amb la qual cosa la plana creix molt i el llista es fa mal de manejar.
Amb Django 1.4 tenim l'opció de crear-nos els nostres propis filtres i dir-li a l'admin que els faci servir. Per posar-vos en situació el que voldríem és que enlloc del filtre com a llista per la clau forana, poguéssim seleccionar l'element a filtrar des d'un desplegable. És veritat que perdem la selecció múltiple, però a l'usuari no li fa res, el que no vol és tota la llista al costat dret del llistat.
Així doncs, el primer que farem serà veure què hi ha respecte als filtres. La documentació de Django es minsa, potser perquè ja avisen que això pot canviar en un futur proper. Ens arriscarem per ara!
El filtre que ens interessa el derivarem de RelatedFieldListFilter
que és qui se n'encarrega de pintar les claus foranes. Val a dir que no
necessitam massa cosa, volem pintar d'una manera diferent els elements,
així que únicament hem de sobreescriure la part que se n'encarrega de
la visualització:
Dins l'admin.py del nostre projecte, per exemple, fem
from django.contrib.admin import RelatedFieldListFilter
class SelectFilter(RelatedFieldListFilter):
template ='filter/select.html'
i ara li hem de dir a Django que el faci servir, per això basta fer que el list_filter agafi aquest classe. Per exemple, suposem que la clau forana es diu localitat i que filtram per altres elements com tipus, actiu. Inicialment tindríem:
list_filter = ('actiu', 'tipus', 'localitat')
llavors el que farem serà:
list_filter = ('actiu, 'tipus',
('localitat', SelectFilter)
)
és a dir, ara podem dir a Django a més del nom del cap a filtrar, la classe que farem servir per presentar el filtrat.
La nostra classe és molt simple, així que la única cosa que hem de fer és pintar la plantilla.
La plantilla base la podeu trobar al codi font de Django mateix, amb el nom de select.html. La modificarem per a que pinti un desplegable:
{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
<select id="s_localidad" style="width:150px;margin-left:5px;">
{% for choice in choices %}
<option {% if choice.selected %} selected="selected" class="selected"{% endif %}
value="{{ choice.query_string|iriencode }}">{{ choice.display }}</option>
{% endfor %}
</select>
Nota: el codi ara per ara no és genèric, és la primera aproximació que vaig fer per sortir del pas :)
La idea però és veure com fa Django els filtres. De fet el que
està fent és mantenir tota la consulta als paràmetres, així que el
que es feia amb la llista ho podem aprofitar també, mostrant el
contingut i al value mantenir el link del filtrat.
Això però no acaba de funcionar, ja que ara no tenim un link i necessitam dir-li a Django que apliqui el nou filtre. Com que l'admin de Django duu jQuery per la part de javascript, doncs el podem aprofitar i afegir codi per a que quan canvii l'element cridi a la url amb el nou filtrat:
<script type="text/javascript">
(function($) {
$(document).ready(function($) {
$("#s_localidad").change(function(){
var ref = $(this, 'option:selected').val();
window.location.href = ref;
});
})
})(django.jQuery);
</script>
i ja ho tenim! Ara sols queda fer una cosa més genèrica i reaprofitable, però a mi al manco ja m'ha servit per veure que això dels filtres té molt bona pinta.
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Django
apibaleares.com
Escrit per Aaloy a 20 de July , 2012 a les 6:01 p.m.
El dimecres passat vàrem posar en producció la nova web de portal immobiliari del Col·legi Oficial d'Agents de la propietat immobiliària de les Illes Baleares, que es mostra baix el domini http://www.apibaleares.com. Com és habitual és una aplicació feta amb Django, i amb la idea de que sigui una aplicació escalable i sobretot mantenible.
El sector immobiliari no passa pel seu millor moment, tot val a dir-ho, però és un projecte que m'ha fet especial il·lusió. Per una part significa tractar amb molta gent que fa servir el programa, cada un amb les seves pròpies sensibilitats, i en un sector on la tecnologia informàtica s'obre pas molt a poc a poc.
És un dels primers projectes que fem amb Django 1.4, així que aprofitaré per fer cinc cèntims del que ha representat. Django 1.4 canvia un poc l'estructura dels projectes per a fer-los més modulars. Per la nostra banda hem aprofitat per també seguir amb el camí iniciat amb PropietariosOnline i SpokenPic i desenvolupar tota l'estructura de vistes mitjançant les class bassed views.
Tot i que hi ha gent a favor i en contra, he de dir que ara per ara, i pels tipus de projectes que fem les CBV són una benedicció. Podem estructura la informació molt millor i fer herència quan convé. En una web com http://www.apibaleares.com on hi ha un cercador adaptat per a cada API i on a més havíem de mantenir la compatibilitat cap enrera, l'herència ha representat poder reaprofitar molt de codi, i sobretot poder tractar amb les complexitats de fer enginyeria inversa de les cerques i continguts d'una manera molt més simple.
La recuperació de les claus d'usuari va representar un problema interessant. Per una part no volíem tenir que donar una clau generada per nosaltres a cada API, i per altra banda volíem que la recuperació de les claus fos el menys intrussiva possible. És a dir, que si algú volgués resetejar la clau ho pogués fer, però si un tercer intenta canviar la clau no ho pogués fer, ja que l'usuari rebrà un e-mail i la clau no es canviarà fins que es faci servir el link que s'envia.
Això ja es podia fer amb django-registration, i val a dir, que encara que està poc documentat, també es pot fer amb les darreres versions de Django. De fet basta un:
<a href="{% url django.contrib.auth.views.password_reset %}">Forgot your password?</a>
i si voleu, personalitzar o sobreescriure les plantilles dins registration (podeu copiar-les del codi font de Django i treballar a partir d'aquí):
login.html password_reset_done.html
password_reset_complete.html password_reset_email.html
password_reset_confirm.html password_reset_form.html
és el mètode que vaig seguir per afegir aquesta funcionalitat a PropietariosOnline. En el cas d'apibaleares, però, vaig preferir fer servir un altre tipus de recuperació, funcionalment idèntica, però que ja fa servir les noves característiques de criptografia de Django. Això em va dur a github i al code de https://github.com/brutasse/django-password-reset. Va ser un procés en paral·lem amb les necessitats d'SpokenPic.
Inicialment django-password-reset tenia una mancança (al meu entendre), que no feia un redirect després de fer un POST amb el canvi de clau. Vaig fer un primer fork i enviar el pegat a Brutasse. Val a dir que era el meu primer fork a github, que jo sóc més de mercurial i per tant de bitbucket. Tot i això després d'alguns intents vaig poder deixar un codi prou decent per a que Brutasse acceptàs el pegat i a més i fes millores addicionals. I vaig aprendre molt pel camí del codi de Brutasse, de com organitzava els unit-tests i del nou mòdul de criptografia de Django 1.4.
És per mi una de les meravelles del codi lliure. Una utilitat que a l'autor "ja li anava bé", la troba algú altra, li fa una millora, l'autor la considera i torna a repensar part del codi. Quan surt la nova versió el que passa és que tots tenim un codi millor que el que hi havia abans. Tothom hi guanya!
No sé si ho heu notat, però m'ho pas molt bé amb la meva feina. Tot i ser de tipus "passador de pena", escriure codi, gestionar projectes i aprendre coses noves m'encanta. En la nostra feina mai ho arribes a saber tot, sempre pots aprendre de com fa les coses un altre. Per mi un dels secrets de passar-ho bé és intentar millorar un poc a cada projecte. Aprofitar la benentesa per anar un pas més enllà, passeta a passeta, sense posar en risc el projecte cercant la bala de planta, però aprenent coses noves a cada passa.
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Django
