【问题标题】:Extending Django-admin's DateFieldListFilter for custom "Upcoming" filter为自定义“即将到来”过滤器扩展 Django-admin 的 DateFieldListFilter
【发布时间】:2019-01-29 05:23:17
【问题描述】:

我正在尝试向 Django Admin DateFieldListFilter 添加一个自定义的“即将到来的”过滤器。这真的很简单,只需选择今天之后的日期。在this thread 的基础上,我能够将 Django 的标准 DateFieldListFilter 扩展为我自己的自定义项,如下所示:

class MyDateTimeFilter(DateFieldListFilter):

    def __init__(self, *args, **kwargs):
        super(MyDateTimeFilter, self).__init__(*args, **kwargs)

        today = datetime.now()    
        self.links += (('Upcoming'), {self.lookup_kwarg_since: today.strftime('%d %B %Y')}),

它在我的过滤器底部正确显示“即将到来”,但点击实际上并没有过滤结果。我不知道我的语法有什么问题,我尝试了很多替代方法......

非常感谢您的帮助!

PS:我使用的是 Python 3.5.2 和 Django 2.0.6

【问题讨论】:

    标签: python django django-admin django-admin-filters


    【解决方案1】:

    没有直接跳到这个,我已经完成了您之前项目所需的内容:

    filters.py:

    import datetime
    
    from django.contrib.admin.filters import DateFieldListFilter
    from django.utils.translation import gettext_lazy as _
    
    class MyDateTimeFilter(DateFieldListFilter):
        def __init__(self, *args, **kwargs):
            super(MyDateTimeFilter, self).__init__(*args, **kwargs)
    
            now = timezone.now()
            # When time zone support is enabled, convert "now" to the user's time
            # zone so Django's definition of "Today" matches what the user expects.
            if timezone.is_aware(now):
                now = timezone.localtime(now)
    
            today = now.date()
    
            self.links += ((
                (_('Upcoming'), {
                    self.lookup_kwarg_since: str(today),
                    self.lookup_kwarg_until: str(today + datetime.timedelta(days=7)),
                }),
            ))
    

    您想添加一些声明以供以后使用(例如,today = now.date()),然后您想使用 self.lookup_kwarg_until 关键字参数,并有一些时间范围作为您的查找日期(为方便起见,我有使用today + datetime.timedelta(days=7),但您可以很容易地将其配置为您需要的任何时间跨度。

    那么你在admin.py 中需要这样的东西:

    from django.contrib import admin
    
    from filters import MyDateTimeFilter
    
    class PostAdmin(admin.ModelAdmin):
        list_filter = (
            ('published_at', MyDateTimeFilter()),
        )
    

    免责声明:这适用于 Python 3.7、Django 2.0*。祈祷这对你有用!

    【讨论】:

    • 请注意,至少在 Django 3.0 中(我没有在其他版本上测试过),您不应该在 list_filter 中初始化过滤器的实例,而是将类传递为 MyDateTimeFilter .
    【解决方案2】:

    感谢您的回答,它确实为我指明了正确的方向。

    我的语法中缺少 _,我试图直接在 admin.py 而不是 filters.py 中创建自定义过滤器。由于我不确定您是指 Django 源文件 django.contrib.admin.filters.py 还是新创建的 model.filters.py 文件,所以我尝试了两种方法,添加自定义过滤器然后导入由于某种原因不起作用我有以下错误代码:

      TypeError: __init__() missing 6 required positional arguments: 'field', 'request', 'params', 'model', 'model_admin', and 'field_path'
    

    好像我的 init 声明不完整。

    但是,鉴于我找到了 Django 过滤器的原始源文件,我能够调整 Django 的原始代码(这可能不推荐,但在我的情况下是无害的)并且效果很好。我无法扩展原始过滤器,但要覆盖它。

    【讨论】:

    • 嗨 Alain,是的,我当然不建议干预核心/基础 Django 项目......使用我的扩展方法,你不会出错! :) 我的问题可以标记为合适的答案吗?
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2012-08-19
    • 1970-01-01
    • 2014-12-01
    • 2015-09-11
    • 2016-10-10
    相关资源
    最近更新 更多