python - queryset - django admin template
Columnas personalizadas utilizando Django admin (2)
Tengo un modelo de Data
, asociado a una tabla como esta (los Data
modelo se componen solo de IntegerField):
subject | year | quarter | sales |
----------------------------------
1 | 2010 | 1 | 20 |
1 | 2010 | 2 | 100 |
1 | 2010 | 3 | 100 |
1 | 2010 | 4 | 20 |
1 | 2011 | 1 | 30 |
1 | 2011 | 2 | 50 |
1 | 2011 | 4 | 40 |
2 | 2010 | 1 | 30 |
2 | 2010 | 2 | 20 |
[..-GO ON this way...]
Quiero tener una tabla django-admin, en columnas de solo lectura ( current year = 2011, quarter = 1
)
subject | sales current year | sales current quarter | sales last year | sales current quarter last year |
----------------------------------------------------------------------------------------------------------
1 | 110 | 30 | 240 | 20
[AND SO ON]
La pregunta es: ¿ Es posible hacer eso usando django-admin? ¿Cuál es la salida?
Algo como esto debería funcionar (no probado):
# models.py
class Data(models.Model):
year = models.DateField()
sales = models.IntegerField()
# ...
def sales_current_year(self):
return self.model._default_manager.get_queryset().filter(year=2012).annotate(Sum(''sales''))
# admin.py
class DataAdmin(admin.ModelAdmin):
list_display = (''sales_current_year'',)
Puede usar métodos en su Model
o su ModelAdmin
como elementos para list_display
. Consulte: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
Ya que estos también son métodos que podrían ser útiles fuera del administrador, sugeriría agregarlos a su Model
.
from django.db.models import Sum
class Data(models.Model):
...
# Method used by `get_current_year_sales` and `get_last_year_sales`
# to stay DRY. Not for use directly in admin.
def get_year_sales(self, year):
qs = self.model._default_manager.filter(year=year)
sales_agg = qs.aggregate(Sum(''sales''))
return sales_agg[''sales__sum'']
# Method used by `get_current_quarter_sales` and `get_last_quarter_sales`
# to stay DRY. Not for use directly in admin.
def get_quarter_sales(self, year, quarter):
qs = self.model._default_manager.filter(year=year, quarter=quarter)
sales_agg = qs.aggregate(Sum(''sales''))
return sales_agg[''sales__sum'']
def get_current_year_sales(self):
return self.get_year_sales(datetime.now().year)
get_current_year_sales.short_description = ''Sales (Current Year)''
def get_last_year_sales(self):
return self.get_year_sales(datetime.now().year-1)
get_last_year_sales.short_description = ''Sales (Last Year)''
def get_current_quarter_sales(self):
# Determine current quarter logic here as `current_quarter`
# `quarter_year` will likely be same as current year here,
# but will need to be calculated for previous quarter
return self.get_quarter_sales(quarter_year, current_quarter)
get_current_quarter_sales.short_description = ''Sales (Current Quarter)''
def get_current_quarter_sales(self):
# Logic here to determine last quarter as `last_quarter`
# Logic to determine what year last quarter was in as `quarter_year`
return self.get_quarter_sales(quarter_year, last_quarter)
get_last_quarter_sales.short_description = ''Sales (Last Quarter)''
El atributo short_description
determina lo que el administrador mostrará como el encabezado de fila para estos métodos. Entonces, una vez que tenga todo esto en su lugar, solo necesita modificar el atributo list_display
su list_display
como:
class DataAdmin(admin.ModelAdmin):
...
list_display = (''subject'', ''get_current_year_sales'', ''get_last_year_sales'', ''get_current_quarter_sales'', ''get_last_quarter_sales'')