首页 > 解决方案 > Create a custom function as a filter in proxy model, django admin

问题描述

I need help to convert CashInhandAdmin->expense as a filter (high and low), have tried below filter but failed because proxy model is inherited from user_profile model but want to filter expense sum that is different model.

Filter

class ExpenseFilter(admin.SimpleListFilter):
    title = 'Expense'
    parameter_name = 'Expense'

    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 (("low", "Filter by low amount"), ("high", "Filter by high amount"))

    def queryset(self, request, queryset):
        """
                Returns the filtered queryset based on the value
                provided in the query string and retrievable via
                `self.value()`.
         """

        if self.value() == "low_price":
            return queryset.order_by("expense")
        elif self.value() == "high_price":
            return queryset.order_by("-expense")
        else:
            return queryset.all()

Model

class CashInhand(user_profile):
    class Meta:
        proxy = True
        verbose_name = "Cash In Hand"
        verbose_name_plural = "Cash In Hand"

Admin

class CashInhandAdmin(admin.ModelAdmin, admin.SimpleListFilter):

    def get_queryset(self, request):
        print(request.GET.get("Expense"))
        qs = super(CashInhandAdmin, self).get_queryset(request)
        return qs.filter(employee__isnull=False).distinct("employee_id").order_by("employee_id")

    def has_delete_permission(self, request, obj=None):
        return False

    def expense(obj):
        exp = models.Expense.objects.filter(created_by_id=obj.employee, status='1').annotate(
            as_float=Cast('amount', FloatField())).aggregate(Sum("as_float"))
        if exp["as_float__sum"]:
            return int(math.ceil(exp["as_float__sum"]))
        else:
            return str(0)

    list_display = (expense,)
    list_filter = (ExpenseFilter)

标签: pythondjangodjango-modelsdjango-admin

解决方案


推荐阅读