Пользовательский фильтр для поля даты в Django Admin, Django 1.2 - PullRequest
3 голосов
/ 27 мая 2011

Это все еще допустимый синтаксис для Django 1.2?

Пользовательский фильтр в Django Admin для Django 1.3 или ниже

Я пробовал это сделать, но опция list_filter в классе admin не распознает мой пользовательский фильтр. Как добавить пользовательский фильтр в фильтр list_filter, чтобы он отображался?

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

Здесь мой 'is_expired_filter' - это мой недавно зарегистрированный пользовательский фильтр, что, по словам автора, он делает так:

    list_filter = ('is_live')

Но это не распознается Django, и я получаю ошибку при загрузке страницы администратора

Тип исключения: неправильно настроен Значение исключения: PositionAdmin.list_filter [2] ссылается на поле is_expired_filter, которое отсутствует в модели Position.

Возможно, моя ошибка в том, что я не уверен, как автор этого вопроса использует исходный код, как только он / она реализует пользовательский фильтр.

Вот оригинальный код:

    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 ]

2 голосов
/ 27 мая 2011

Теперь, когда я знаю, что вы хотите, я предполагаю, что у вас есть модель, которую вы хотите отфильтровать по 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']
0 голосов
/ 27 мая 2011

Почти копирование вашей ссылки Пользовательский фильтр в Django Admin на Django 1.3 или ниже слово в слово, я придумал это.



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 будет полем, которое вы хотите отфильтровать.

...