django - 简单列表过滤器默认值

标签 django django-admin django-admin-filters

我的模型上有一个 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' 而不是 TrueFalse > 在您的 querystring 方法中,但是您会注意到正确的选择不会突出显示,因为元组中的第一个元素不匹配(然后您将字符串与 bool 值进行比较)。我也尝试制作元组字符串中的第一个元素,但随后我必须进行字符串比较或 eval 才能将 'True'True,这有点丑陋/不安全。所以最好坚持使用整数,就像我的例子一样。

关于django - 简单列表过滤器默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18603750/

相关文章:

python - 如何撤消 Django 中未完成迁移的更改

python - Django 管理员 : Filter many2many relations independently

python - 如何修复 djangos 的 decotators 错误 : Wrapped class must subclass ModelAdmin

django - Django 管理中日期字段的自定义过滤器,Django 1.2

django - 使用 Django 管理站点的多选字段

python - 如何在 django 管理页面中自动为我的所有模型创建 list_filters?

python - 使用 django 和 bootstrap 类创建单选表单的问题

python - 如何在 Django 中添加带有通用外键的 unique_together

Django 管理员内联 : select all for delete?

python - django 应用程序中模型的自连接是否是可接受的模式?