为自定义 "Upcoming" 过滤器扩展 Django-admin 的 DateFieldListFilter
Extending Django-admin's DateFieldListFilter for custom "Upcoming" filter
我正在尝试向 Django Admin DateFieldListFilter 添加自定义 "Upcoming" 过滤器。非常简单,只需选择今天之后的日期。在 的基础上,我能够将 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')}),
它在我的过滤器底部正确显示 "Upcoming",但点击并没有实际过滤结果。我不知道我的语法有什么问题,我尝试了很多替代方法...
非常感谢您的帮助!
PS: 我正在使用 Python 3.5.2 和 Django 2.0.6
不用直接跳到这个,我已经完成了你在上一个项目中所需要的:
在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*。祝你好运!
感谢您的回答,它确实为我指明了正确的方向。
我的语法中缺少 _,我试图直接在 admin.py 而不是 [=30 中创建自定义过滤器=]。因为我不确定您指的是 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 的原始代码(这可能不被推荐,但对我来说无害)并且效果很好。我无法扩展原始过滤器,但可以覆盖它。
我正在尝试向 Django Admin DateFieldListFilter 添加自定义 "Upcoming" 过滤器。非常简单,只需选择今天之后的日期。在
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')}),
它在我的过滤器底部正确显示 "Upcoming",但点击并没有实际过滤结果。我不知道我的语法有什么问题,我尝试了很多替代方法...
非常感谢您的帮助!
PS: 我正在使用 Python 3.5.2 和 Django 2.0.6
不用直接跳到这个,我已经完成了你在上一个项目中所需要的:
在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*。祝你好运!
感谢您的回答,它确实为我指明了正确的方向。
我的语法中缺少 _,我试图直接在 admin.py 而不是 [=30 中创建自定义过滤器=]。因为我不确定您指的是 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 的原始代码(这可能不被推荐,但对我来说无害)并且效果很好。我无法扩展原始过滤器,但可以覆盖它。