Search code examples
djangodjango-modelsdjango-admindjango-filter

How to filter the model property value using custom filter in Django admin


I have the model with property and custom filter. Depending on the custom filter value, I need to update the _approved property value (not the model queryset) on the Django admin page.

model.py

class Model(models.Model):
    created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name='Created')
    updated = models.DateTimeField(auto_now_add=False, auto_now=True, verbose_name='Updated')

    @property
    def _approved(self):
        return ModelRecordRelation.objects.filter(model_id=self.id, status='A').count()

admin.py

class TimeFrameFilter(SimpleListFilter):
    title = 'timeframe'
    parameter_name = 'timeframe'

    def lookups(self, request, model_admin):
        return [
            ('Today', 'Today'),
            ('ThisWeek', 'This Week'),
        ]

    def queryset(self, request, queryset):

        return queryset.filter()


class ModelAdmin(admin.ModelAdmin):
    list_display = ['created', 'updated']

    class Meta:
        model = Model

    def approved(self, obj):
        return obj._approved

    approved.admin_order_field = 'approved'

Solution

  • You have to customize get_queryset in you admin class:

    class ModelAdmin(admin.ModelAdmin):
        list_display = ['created', 'updated', 'approved']
        list_filter = [TimeFrameFilter]
    
        def get_queryset(self, request):
            queryset = super().get_queryset(request)
            queryset = queryset.annotate(approved_count=Count('modelrecordrelation', filter=models.Q(modelrecordrelation__status='A')))
            return queryset
    
        def approved(self, obj):
            return obj.approved_count
    
        approved.admin_order_field = 'approved_count'