1

在 django-admin 中,对于模型,我必须按日期时间范围进行过滤。

我发现了这个: https ://github.com/DXist/django-daterange-filter/blob/master/daterange_filter/filter.py 效果很好,但仅适用于日期范围而不是日期时间范围。

所以我试图修改,这是我自己的版本:

class DateRangeForm(forms.Form):

    def __init__(self, *args, **kwargs):
        field_name = kwargs.pop('field_name')
        super(DateRangeForm, self).__init__(*args, **kwargs)

        self.fields['%s__gte' % field_name] = forms.DateTimeField(
            label='', widget=AdminSplitDateTime(
                attrs={'placeholder': _('From date')}), localize=True,
            required=False)

        self.fields['%s__lte' % field_name] = forms.DateTimeField(
            label='', widget=AdminSplitDateTime(
                attrs={'placeholder': _('To date')}), localize=True,
            required=False)


class DateRangeFilter(admin.filters.FieldListFilter):
    template = 'admin/daterange_filter/filter.html'

    def __init__(self, field, request, params, model, model_admin, field_path):
        self.lookup_kwarg_since = '%s__gte' % field_path
        self.lookup_kwarg_upto = '%s__lte' % field_path
        super(DateRangeFilter, self).__init__(
            field, request, params, model, model_admin, field_path)
        self.form = self.get_form(request)

    def choices(self, cl):
        return []

    def expected_parameters(self):
        return [self.lookup_kwarg_since, self.lookup_kwarg_upto]

    def get_form(self, request):
        return DateRangeForm(data=self.used_parameters,
                             field_name=self.field_path)

    def queryset(self, request, queryset):
        if self.form.is_valid():
            # get no null params
            filter_params = dict(filter(lambda x: bool(x[1]),
                                        self.form.cleaned_data.items()))

            for k, v in filter_params.items():
                if k.endswith('__lte'):
                    filter_params[k] = v + timedelta(days=1)

            return queryset.filter(**filter_params)
        else:
            return queryset


admin.filters.FieldListFilter.register(lambda f: isinstance(f, models.DateTimeField), DateRangeFilter)

“前端”端它正在工作..它显示了 AdminSplitDateTime 小部件,但是当我提交过滤器表单时,我得到:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/admin/erp/ordine/?data_creazione__gte_0=29%2F05%2F2013&data_creazione__gte_1=12%3A42%3A10&data_creazione__lte_0=&data_creazione__lte_1=

Django Version: 1.5.1
Python Version: 2.7.5
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'account',
 'south',
 'mptt',
 'erp',
 'tinymce')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in wrapper
  372.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
  202.             return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in changelist_view
  1180.                 self)
File "C:\Python27\lib\site-packages\django\contrib\admin\views\main.py" in __init__
  73.         self.query_set = self.get_query_set(request)
File "C:\Python27\lib\site-packages\django\contrib\admin\views\main.py" in get_query_set
  303.          use_distinct) = self.get_filters(request)
File "C:\Python27\lib\site-packages\django\contrib\admin\views\main.py" in get_filters
  100.             if not self.model_admin.lookup_allowed(key, value):
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in lookup_allowed
  263.                 model = field.rel.to

Exception Type: AttributeError at /admin/erp/ordine/
Exception Value: 'NoneType' object has no attribute 'to'

我准备了一个半空的 django 项目(1 个轻型模型,管理员设置,dev.db sqlite3)只是为了测试这个问题:你可以在这里找到它:https ://dl.dropboxusercontent.com/u/53953129/ test_project.zip

4

2 回答 2

0

您尚未发布此过滤器的客户端代码。什么值在 options.py 中获得“字段”变量?

于 2013-05-29T20:12:24.803 回答
0

不过情况没有改变……我添加了一个小测试项目来玩

于 2013-06-13T17:57:19.830 回答