Django class based views - Epílogo

3 de Marzo de 2012 · 2 min de lectura

Logo APSL

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 = ('slug',)

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('tutorial_list_sample')
    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:

<a href="{% url tutorial_list_sample %}">All</a>|
<a href="{% url tutorial_list_sample %}?filter=positive">Positive</a>|
<a href="{% url tutorial_list_sample %}?filter=negative">Negative</a>

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('filter')
        if filter == 'positive':
            queryset = queryset.filter(ammount__gt=0)
        elif filter== 'negative':
            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.

Comparte este artículo
Artículos relacionados