Quem sou eu

Minha foto

Formado em Computação, desenvolvedor web, interessado em tecnologia, metaleiro e um gamer inveterado.

Pesquisar

quinta-feira, 10 de abril de 2014

Como fazer um filtro personalizado pro admin do Django com o SimpleListFilter

Muitas vezes os filtros automáticos que o admin do django faz são muito úteis. Contudo há momentos que simplesmente colocar o nome do atributo no list_filter não atende. Pra esses momentos temos o SimpleListFilter. 

Ano de Copa, álbuns de figurinhas à venda, suponhamos que, assim como eu, você tenha feito (ou queira fazer)  um sistema pra gerenciamento das figurinhas da Panini.

O models.py ficaria assim:

# coding: utf-8
from django.db import models
class Figurinha(models.Model):
 """(Figurinha description)"""
 numero = models.CharField(max_length=3, verbose_name=u'Número')
 quantidade = models.IntegerField(default=0)
 especial = models.BooleanField(default=False, help_text='Figurinhas brilhantes e/ou diferenciadas')
 data = models.DateTimeField(null=True, blank=True, auto_now=True, verbose_name=u'Modificação')

 class Meta:
  ordering = ('id',)

 def __unicode__(self):
  return self.numero



Algumas explicações antes de continuarmos:

  • Número é sim um CharField, pois neste álbum existem figurinhas alfanuméricas (J1, J2, J3, J4, L1, L2, L3, L4 e W1)
  • Quantidade será o campo atualizável, onde 0 são as figurinhas que faltam, 1 pra colada no álbum e maiores que 1 pra quantidade de repetidas. Ex: Quantidade = 2, são 1 no álbum e 1 repetida.
  • Data será atualizada a cada atualização da figurinha para que seja possível emitir a data da ultima atualização da lista

E o admin.py :

class StatusListFilter(admin.SimpleListFilter):
 # Human-readable title which will be displayed in the
 # right admin sidebar just above the filter options.
 title = 'Status'

 # Parameter for the filter that will be used in the URL query.
 parameter_name = 's'

 def lookups(self, request, model_admin):
  """
  Returns a list of tuples. The first element in each
  tuple is the coded value for the option that will
  appear in the URL query. The second element is the
  human-readable name for the option that will appear
  in the right sidebar.
  """
  return (
   ('falta', 'Falta'),
   ('tenho', 'Tenho'),
   ('repetida', 'Repetida'),
  )

 def queryset(self, request, queryset):
  """
  Returns the filtered queryset based on the value
  provided in the query string and retrievable via
  `self.value()`.
  """
  # Compare the requested value (either '80s' or 'other')
  # to decide how to filter the queryset.
  if self.value() == 'falta':
   return queryset.filter(quantidade=0)
  elif self.value() == 'tenho':
   return queryset.filter(quantidade__gt=0)
  elif self.value() == 'repetida':
   return queryset.filter(quantidade__gt=1)

class FigurinhaAdmin(admin.ModelAdmin):
 search_fields = ('numero',)
 list_display = ('numero','quantidade','especial','data')
 list_filter = ['quantidade','especial','data',StatusListFilter]
 list_editable = ['quantidade',]
 date_hierarchy = 'data'
 readonly_fields = ['numero','especial',]
 save_on_top = True

 fieldsets = (
  (u'Número', {'fields': ('numero',)}),
  ('Quantidade', {'fields': ('quantidade',)}),
  ('Especial', {'fields': ('especial',)}),
 )

admin.site.register(Figurinha, FigurinhaAdmin)


Para mais informações sobre o SimpleListFilter, consulte https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter

hasta!