El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Django class based views (II)

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'^test3/(?P<id>\d+)/$', Test3View.as_view(), name="test3-class-view"),

llavors get_context_data conté el diccionari {'id': 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 = 'main/index.html'

def get_context_data(self, **kwargs):
context = super(Test3View, self).get_context_data(**kwargs)
context['id'] = self.kwargs.get('id')
context['msg'] = u'Hello blog!'
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'una altra classe on ja s'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'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 = 'main/index.html'

def get_message(self):
return u'Hello blog'

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

I encara tenim més flexibilitat, gràcies al mixin TemplateResponseMixin podem definir quina plantilla s'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 = 'main/index.html'

def get_message(self):
return u'Hello blog'

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

def get_context_data(self, **kwargs):
context = super(Test3View, self).get_context_data(**kwargs)
context['id'] = self.kwargs.get('id')
context['msg'] = 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...

blog comments powered by Disqus