到目前为止,我一直在使用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获得的一周结束时间。
我希望过滤器中有2个框From date
和To date
加DatePicker
,与django-daterange_filter
的实现非常相似。
我知道我可以在过滤器中添加template
,但是如何修改lookups
以同时允许两个变量?
答案 0 :(得分:0)
我终于找到了办法。我必须从filter.py
模块中修改daterange_filter
,然后创建第二个名为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>
希望这对某人有用。