Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom columns using Django admin

Tags:

I have a model Data, associated to a table like this (The model Data is made up of only 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...] 

I want to have a django-admin table, in read-only having columns (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] 

The question is: It is possible do that using django-admin? What's the way out?

like image 731
zambotn Avatar asked Feb 06 '12 17:02

zambotn


People also ask

Can we customize Django admin panel?

The Django admin is a powerful built-in tool giving you the ability to create, update, and delete objects in your database using a web interface. You can customize the Django admin to do almost anything you want.

How do I display columns in Django?

To display both the three columns in the admin site model list page, you need edit the Django app's admin.py file ( dept_emp / admin.py ), then define a class which extends django. contrib. admin. ModelAdmin class.

Is Django's admin interface customizable if yes then how?

In this article, we will discuss how to enhance Django-admin Interface. Let us create an app called state which has one model with the same name(state). When we register app to admin.py it shows like. Now lets' customize django admin according to available options.

How use Django admin panel?

To login to the site, open the /admin URL (e.g. http://127.0.0.1:8000/admin ) and enter your new superuser userid and password credentials (you'll be redirected to the login page, and then back to the /admin URL after you've entered your details).


2 Answers

You can use methods on your Model or your ModelAdmin as items for list_display. See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display

Since these are methods that might be useful outside the admin, as well, I'd suggest adding them to your 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)' 

The short_description attribute determines what the admin will show as the row header for these methods. So, once you have all this in place, you need only modify your ModelAdmin's list_display attribute like:

class DataAdmin(admin.ModelAdmin):     ...     list_display = ('subject', 'get_current_year_sales', 'get_last_year_sales', 'get_current_quarter_sales', 'get_last_quarter_sales') 
like image 94
Chris Pratt Avatar answered Oct 02 '22 14:10

Chris Pratt


Something like this should work (untested):

# 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',) 
like image 36
dan-klasson Avatar answered Oct 02 '22 13:10

dan-klasson