El Blog de Trespams

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

Django class based views (VI) - Lists

En aquesta sisena entrega (que hi ha algú per aquí ho ja us heu dormit tots?) veurem com podem mostrar llistes d'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 plantilla per defecte, formada pel nom del model i el sufixe '_list'.

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'url:

url(r'^tutorial/sample/list/$', SampleListView.as_view(), name='tutorial_list_sample'),

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'objectes del model. De manera que podem fer una plantilla del tipus:

<!DOCTYPE html PUBLIC "-//W3C//DTDT XHTML 1.1/EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"xml:lang>
<head>
<title>test</title>
</head>
<body>
<h1>Sample Detail List</h1>
<table border="1">
{% for sample in object_list %}
<tr>
<td><a href="{% url tutorial_update_sample sample.slug %}"> {{sample.slug}}</a><td/>
<td>{{sample.name}}<td/> <td>{{sample.ammount}}<td/>
<td>{{sample.comments}}<td/>
<td> <a href="{% url tutorial_delete_sample sample.slug %}">Delete</a>|<a href="{% url tutorial_create_sample %}">Create</a></td> </tr>
{% endfor %}
</tr>
</table>
</body>
</html>

Fixau-vos que no estic fent herència, l'html és molt simple etc. L'important aquí és veure com podem recórrer la llista d'objectes per montar les files d'una taula, i com amb el que ja sabem del CRUD podem enllaçar amb els manteniments.

Ara a l'hora de crear, editar o esborrar un registre podem elegir entre mostrar el registre o anar al llistat, afegint

success_url = reverse_lazy('tutorial_list_sample')

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'afegir l'atribut paginate_by que ens determinarà el nombre màxim d'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 %}
<a href="{% url tutorial_list_sample %}?page={{ page_obj.previous_page_number }}">Previous> </a>
{% endif %}

Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.

{% if page_obj.has_next %}
<a href="{% url tutorial_list_sample %}?page={{ page_obj.next_page_number }}">Next </a>

{% 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é fem us 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'edició

blog comments powered by Disqus