我使用https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter上的教程为我的ModelAdmin编写了自定义列表过滤器。
当从项目中取出进入测试环境并直接输入过滤值时,它可以正常工作。但是,在实际项目中,它会显示过滤器选项,但在选择过滤器时不会更改结果。
奇怪的是,参数设置为“平衡”,查找列表定义为“正”,“负”和“已结算”;但相应的URL查询字符串只会显示?e=1
。即使我直接输入查询字符串(例如?balance=positive
),我也会被重定向到?e=1
并查看所有对象。
这是代码:
class AccountBalanceFilter(admin.SimpleListFilter):
title = "Kontostand"
parameter_name = "balance"
def lookups(self, request, model_admin):
return (("positive", "Positiv"),
("negative", "Negativ"),
("settled", "Ausgeglichen"),)
def queryset(self, request, queryset):
filter = self.value()
if filter is None:
return queryset
elif filter == "positive":
filtered_set = {account for account in queryset if account.get_current_balance() > 0}
elif filter == "negative":
filtered_set = {account for account in queryset if account.get_current_balance() < 0}
elif filter == "settled":
filtered_set = {account for account in queryset if account.get_current_balance() == 0}
else:
raise ValueError(f"The account balance filter only accepts filter values of 'positive', 'negative', or 'settled', but was given '{self.value()}'!")
return filtered_set
有什么建议吗?
答案 0 :(得分:0)
好的,经过一些调试后我发现?e=1
查询字符串是管理员告诉我们数据格式错误的方式......我原本希望在这种情况下看到异常。
问题实际上非常简单:管理员需要一个Queryset对象,并且不了解常规(Python)集。由于无法在Django的数据库API之外构造Queryset,因此解决方案是从我想要的对象中提取id并返回由该id列表过滤的Queryset,如下所示:
[...]
elif filter == "positive":
filtered_ids = [account.id for account in queryset if account.get_current_balance() > 0]
[...]
return Account.objects.filter(id__in=filtered_ids)
这就是工作。现在我也可以按照here的说明订购。