【问题标题】:Filter range date from custom property using SimpleListFilter使用 SimpleListFilter 从自定义属性中过滤范围日期
【发布时间】:2014-09-21 16:55:09
【问题描述】:

到目前为止,我一直在使用 django-daterange_filter 过滤 Django Admin 范围内的日期。 只要日期是模型中的一个字段,它就非常有效。

但是,现在我的date 是模型中的一个属性,所以我使用的是 SimpleListFilter。

这就是我现在一直在做的事情并且效果很好:

class CalibrationFilter(admin.SimpleListFilter):
    title = ('Last calibration')

    parameter_name = 'calibrationdate'

    def lookups(self,request,mode):
        return (
            ('this_week','This week'),
            ('1_week','Last week'),
            ('2_week','2 weeks ago'),
            ('3_week','3 weeks ago'),
            )

    def queryset(self,request,queryset):
        if self.value() == None:
            return queryset

        if self.value() == 'this_week':
            day = date.today()
            startdate = week_range(day)[0]
            enddate = week_range(day)[1]
            shelves = Shelf.objects.raw(""" [..] here is MySQL query with LEFT JOIN [..] 
                                         WHERE table.date 
                                         BETWEEN '%s' and '%s' """ %
                                         (startdate.strftime('%Y-%m-%d'),
                                          enddate.strftime('%Y-%m-%d'))
                                        )
            return queryset.filter(id__in=[a.id for a in shelves])

        else:
            weeks = '%s' % (self.value())
            num_of_weeks , weeks = weeks.split('_',1)
            day = date.today() - datetime.timedelta(days=int(num_of_weeks)*7)
            startdate = week_range(day)[0]
            enddate = week_range(day)[1]

            shelves = Shelf.objects.raw(""" [..] here is MySQL query with LEFT JOIN [..] 
                                         WHERE table.date 
                                         BETWEEN '%s' and '%s' """ %
                                         (startdate.strftime('%Y-%m-%d'),
                                          enddate.strftime('%Y-%m-%d'))
                                        )
            return queryset.filter(id__in=[a.id for a in shelves])

week_range() 是一个函数,用于确定我从here 获得的一周的结束和开始。

我希望过滤器中有两个框,From dateTo dateDatePicker,非常类似于 django-daterange_filter 的实现。

我知道我可以在过滤器中添加template,但是如何修改lookups 以同时允许两个变量?

【问题讨论】:

    标签: python django date filter django-admin


    【解决方案1】:

    我终于找到了办法。我必须从daterange_filter 模块编辑filter.py 并创建第二个模板,我称之为filter2.html

    #admin.py
    from daterange_filter2.filter import DateRangeFilter, DateBookFilter
    
    class LibraryAdmin(admin.ModelAdmin):
    list_filter = ('name', ('date', DateRangeFilter), ('shelf__book__date', DateBookFilter),)
    
    admin.site.register(Library, LibraryAdmin)
    

    然后在filter.py中添加以下内容:

    #daterange_filter/filter.py
    class DateBookFilter(admin.filters.FieldListFilter):
        template = 'daterange_filter/filter2.html'
    
        def __init__(self, field, request, params, model, model_admin, field_path):
            self.parameter_name = field.name
            self.lookup_kwarg_since = '%s__gte' % self.parameter_name
            self.lookup_kwarg_upto = '%s__lte' % self.parameter_name
            super(DateBookFilter, self).__init__(
                field, request, params, model, model_admin, self.parameter_name)
            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):
            print self.used_parameters
            return DateRangeForm(data=self.used_parameters,
                                 field_name=self.parameter_name)
    
        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()))
                from_date = self.form.cleaned_data['%s__gte' % self.parameter_name]
                to_date = self.form.cleaned_data['%s__lte' % self.parameter_name]
                #If none are selected, we return the queryset without filtering
                if from_date is None and to_date is None: 
                    return queryset
                #if "From" is empty we will look for records before "To"
                if from_date is None:
                    return queryset.filter(shelf__book__date__lt=to_date).order_by('-shelf__book__date')
                #if "To" is empty we will look for records after "From"
                if to_date is None:
                    return queryset.filter(shelf__book__date__gt=from_date).order_by('-shelf__book__date')
                #if none of the above then both fields are set so we look between "From" and "To"
                else:
                    return queryset.filter(shelf__book__date__range=(from_date,to_date)).order_by('-shelf__book__date')
            else:
                return queryset
    
    
    admin.filters.FieldListFilter.register(
       lambda f: isinstance(f, models.DateField), DateCalibrationFilter)
    

    最后创建新模板,我从模板中删除了{{ spec.form.media }},因为它在表单中生成了重复的“Today”和“Calendar Picker”:

    #templates/daterange_filter/filter2.html
    {% load i18n admin_static %}
    <h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
    <link rel="stylesheet" type="text/css" href="{% static "admin/css/widgets.css" %}" />
    <style>
        .calendarbox, .clockbox {
            /* Make sure the calendar widget popover displays in front of the sidebar */
            z-index: 1100;
            margin-left: -251px;
        }
        .datetimeshortcuts a{
            /* Make text for "Today" a bit smaller so it appears on one line. */
            font-size: 8pt;
        }
    </style>
    <form method="GET" action="">
    
        {{ spec.form.as_p }}
        <p>
        <input type="submit" value="{% trans "Search" %}">
        <input type="reset" value="{% trans "Clear" %}">
        </p>
    </form>
    

    希望这对某人有帮助。

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 2010-12-12
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多