Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用SimpleListFilter从自定义属性筛选范围日期_Python_Django_Date_Filter_Django Admin - Fatal编程技术网

Python 使用SimpleListFilter从自定义属性筛选范围日期

Python 使用SimpleListFilter从自定义属性筛选范围日期,python,django,date,filter,django-admin,Python,Django,Date,Filter,Django Admin,到目前为止,我一直在使用django-daterange\u过滤器在django Admin中过滤某个范围内的日期。 只要日期是模型中的一个字段,这种方法就非常有效 但是,现在我的date是模型中的一个属性,因此我使用SimpleListFilter 我现在就是这样做的,效果很好: class CalibrationFilter(admin.SimpleListFilter): title = ('Last calibration') parameter_name = 'cal

到目前为止,我一直在使用django-daterange\u过滤器在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\u range()
是一个函数,用于确定我从中获得的一周的结束和开始时间

我希望过滤器中有两个框,分别带有
起始日期
截止日期
,以及
日期选择器
,与
django-daterange\u过滤器的实现非常类似


我知道我可以在过滤器中添加
模板
,但是如何修改
查找
以允许同时使用两个变量?

我终于找到了一种方法。我必须从
daterange\u 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}
,因为它在表单中生成了重复的“今天”和“日历选择器”:

#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>
#模板/daterange_过滤器/filter2.html
{%load i18n admin_static%}
{{filter_title}{%endblocktrans%}通过{filter_title}}{%endblocktrans%}使用过滤器{%blocktrans=title%}
.calendarbox、.clockbox{
/*确保侧边栏前面显示日历小部件弹出窗口*/
z指数:1100;
左边距:-251px;
}
.datetimeshortcuts a{
/*将“今天”的文本缩小一点,使其显示在一行上*/
字号:8pt;
}
{{spec.form.as_p}}

希望这对某人有帮助