Django Admin中的日期字段自定义过滤器,Django 1.2

时间:2011-05-27 16:40:11

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

这是Django 1.2的有效语法吗?

Custom Filter in Django Admin on Django 1.3 or below

我试过了,但是admin类中的list_filter选项无法识别我的自定义过滤器。 如何将自定义过滤器添加到list_filter以便显示?

    class MyModelAdmin(admin.ModelAdmin):
        ...
        list_filter = ['is_expired_filter']

这里我的'is_expired_filter'是我新注册的自定义过滤器,这是作者所说他喜欢的:

    list_filter = ('is_live')

但Django无法识别这一点,加载管理页面时出现的错误是

  

异常类型:NotperlyConfigured   例外值:'PositionAdmin.list_filter [2]'指的是模型'Position'中缺少的字段'is_expired_filter'

也许我的错误在于,一旦他/她实现自定义过滤器,我不确定该问题的作者是如何使用原始代码的。

以下是原始代码:

    def is_live(self):
        if self.when_to_publish is not None:
            if ( self.when_to_publish < datetime.now() ):
                return """ <img alt="True" src="/media/img/admin/icon-yes.gif"/> """
        else:
            return """ <img alt="False" src="/media/img/admin/icon-no.gif"/> """      

    is_live.allow_tags = True

2 个答案:

答案 0 :(得分:2)

现在我已经掌握了我认为你想要的东西,我假设你有一个你希望通过DateField过滤的模型:

class Position(models.Model):
    expiration_date = models.DateField()
    ...

您现在应该修改为

class Position(models.Model):
    expiration_date = models.DateField()
    expiration_date.is_expired_filter = True
    ...

您要做的是将admin.py添加到新的过滤器类

from django.contrib.admin.filterspecs import FilterSpec, DateFieldFilterSpec
from django.utils.translation import ugettext as _
from datetime import datetime, date
class ExpiredFilterSpec(DateFieldFilterSpec):
    """
    Adds filtering by future and previous values in the admin
    filter sidebar. Set the is_expired_filter filter in the model field
    attribute 'is_expired_filter'.
    my_model_field.is_expired_filter = True
    """
    def __init__(self, f, request, params, model, model_admin, **kwargs):
        super(ExpiredFilterSpec, self).__init__(f, request, params, model,
                                                model_admin, **kwargs)
        today = date.today()
        self.links = (
            (_('All'), {}),
            (_('Not Expired'), {'%s__lt' % self.field.name: str(today),
                   }),
            (_('Expired'), {'%s__gte' % self.field.name: str(today),
                    }))
    def title(self):
        return "Filter By Expiration Date"
# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'is_expired_filter', False),
                                   ExpiredFilterSpec))


class PositionAdmin(admin.ModelAdmin):
    list_filter = ['expiration_date']

答案 1 :(得分:0)

我几乎一字不差地复制您的链接Custom Filter in Django Admin on Django 1.3 or below,我想出了这个。



from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec, DateFieldFilterSpec
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _
from datetime import datetime

class IsExpiredFilterSpec(DateFieldFilterSpec):
    """
    Adds filtering by future and previous values in the admin
    filter sidebar. Set the is_expired_filter filter in the model field 
    attribute 'is_expired_filter'.
    my_model_field.is_expired_filter = True
    """

    def __init__(self, f, request, params, model, model_admin):
        super(IsExpiredFilterSpec, self).__init__(f, request, params, model,
                                                   model_admin)
         # -- You'll need to edit this to make it do what you want. --
#        today = datetime.now()
#        self.links = (
#            (_('Any'), {}),
#            (_('Yes'), {'%s__lte' % self.field.name: str(today),
#                       }),
#            (_('No'), {'%s__gte' % self.field.name: str(today),
#                    }),
#            
#        )


    def title(self):
        return "Is Expired"

\# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'is_expired_filter', False),
                                   IsExpiredFilterSpec))

class MyModelAdmin(admin.ModelAdmin):
    ...
    MODEL_FIELD_TO_FILTER.is_expired_filter = True
    list_filters = ['MODEL_FIELD_TO_FILTER']

更新:感谢jimbob做出改变。 MODEL_FIELD_TO_FILTER将是您要过滤的字段。