Custom columns using Django admin

后端 未结 2 1608
灰色年华
灰色年华 2020-12-15 18:25

I have a model Data, associated to a table like this (The model Data is made up of only IntegerField):

subject | year | quarter | s         


        
相关标签:
2条回答
  • 2020-12-15 18:32

    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',)
    
    0 讨论(0)
  • 2020-12-15 18:40

    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')
    
    0 讨论(0)
提交回复
热议问题