我的模型上有一个 bool 字段,表示某人是否已取消其成员(member)资格。我正在尝试创建一个自定义 SimpleListFilter 来允许过滤此字段。
但是,我真的想只显示那些默认情况下未取消的。有什么办法默认选择“否”选项吗?到目前为止,这是我的过滤器:
class CanceledFilter(SimpleListFilter):
title = 'Canceled'
# Parameter for the filter that will be used in the URL query.
parameter_name = 'canceled'
def lookups(self, request, model_admin):
return (
(True, 'Yes'),
(False, 'No'),
)
def queryset(self, request, queryset):
if self.value() is True or self.value() is None:
return queryset.filter(canceled=True)
if self.value() is False:
return queryset.filter(canceled=False)
编辑: 我应该更清楚一点。我专门尝试在管理界面中执行此操作。当我将上述过滤器添加为 admin 中的 list_filter 时。我在管理页面一侧看到一个过滤器,有 3 个选项:全部、是和否。
我希望默认选择“否”或不设置任何选项。相反,默认情况下始终设置“全部”选项。是否有一些简单的方法来设置默认过滤器选择或类似的东西。
基本上在管理员中,当他们查看成员时,我只想默认显示事件的(未取消的)。如果他们点击“全部”或"is",那么我想显示已取消的。
更新: 请注意,这与问题 Default filter in Django admin 相同,但我这个问题已经有 6 岁了。接受的答案被标记为需要 Django 1.4。我不确定这个答案是否仍然适用于较新的 Django 版本,或者仍然是最好的答案。
考虑到另一个问题的答案已经过时了,我不确定我们应该如何继续。我认为没有任何方法可以将两者合并。
最佳答案
不得不做同样的事情并偶然发现了你的问题。这就是我在代码中修复它的方法(适应您的示例):
class CanceledFilter(SimpleListFilter):
title = 'Canceled'
# Parameter for the filter that will be used in the URL query.
parameter_name = 'canceled'
def lookups(self, request, model_admin):
return (
(2, 'All'),
(1, 'Yes'),
(0, 'No'),
)
def queryset(self, request, queryset):
if self.value() is None:
self.used_parameters[self.parameter_name] = 0
else:
self.used_parameters[self.parameter_name] = int(self.value())
if self.value() == 2:
return queryset
return queryset.filter(cancelled=self.value())
需要一些解释。查询字符串只是 URL 的一部分,正如其名称所暗示的那样:查询字符串。您的值以字符串形式出现,而不是 bool 值或整数。因此,当您调用 self.value()
时,它会返回一个字符串。
如果您检查单击“是/否”时获得的 URL,在不使用自定义列表过滤器时,您会看到它将其编码为 1/0,而不是 True/False。我采用了相同的方案。
为了完整性和我们 future 的读者,我还为全部添加了 2 个。未经验证,我假设之前是None
。但是,当未选择任何内容时,也会使用 None
,默认为 All。但在我们的例子中,它需要默认为 False,所以我必须选择一个不同的值。如果您不需要 All 选项,只需删除 queryset
方法中的最后一个 if block 以及 lookups
方法中的第一个元组即可。
既然如此,它是如何工作的呢?诀窍在于意识到 self.value()
只是返回:
self.used_parameters.get(self.parameter_name, None)
它可以是一个字符串,也可以是None
,具体取决于该键是否在字典中找到。这就是中心思想:我们确保它包含整数而不是字符串,以便可以在对 queryset.filter()
的调用中使用 self.value()
。对 All 的值进行特殊处理,即 2:在本例中,仅返回 queryset
而不是过滤后的查询集。另一个特殊值是None
,这意味着字典中没有键parameter_name
。在这种情况下,我们创建一个值为 0 的值,以便 False
成为默认值。
注意:你的逻辑不正确;您希望默认情况下不取消,但您将 None
视为与 True
相同。我的版本纠正了这个问题。
ps:是的,您可以检查 'True'
和 'False'
而不是 True
和 False
> 在您的 querystring
方法中,但是您会注意到正确的选择不会突出显示,因为元组中的第一个元素不匹配(然后您将字符串与 bool 值进行比较)。我也尝试制作元组字符串中的第一个元素,但随后我必须进行字符串比较或 eval
才能将 'True'
与 True
,这有点丑陋/不安全。所以最好坚持使用整数,就像我的例子一样。
关于django - 简单列表过滤器默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18603750/