123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- from __future__ import unicode_literals
- import datetime
- from collections import OrderedDict
- try:
- import pytz
- except ImportError:
- pytz = None
- from django import forms
- from django.conf import settings
- from django.contrib import admin
- from django.contrib.admin.widgets import AdminDateWidget
- from django.template.defaultfilters import slugify
- from django.utils.translation import ugettext as _
- from django.utils.encoding import smart_text
- from django.utils.html import format_html
- from django.core.urlresolvers import reverse
- try:
- from django.contrib.admin.utils import get_model_from_relation
- except ImportError: # Django 1.6
- from django.contrib.admin.util import get_model_from_relation
- try:
- from django.forms.utils import flatatt
- except ImportError: # Django 1.6
- from django.forms.util import flatatt
- def make_dt_aware(dt):
- if pytz is not None and settings.USE_TZ:
- timezone = pytz.timezone(settings.TIME_ZONE)
- if dt.tzinfo is not None:
- dt = timezone.normalize(dt)
- else:
- dt = timezone.localize(dt)
- return dt
- class RelatedFieldAjaxListFilter(admin.RelatedFieldListFilter):
- ajax_attrs = None
- def has_output(self):
- return True
- def field_choices(self, field, request, model_admin):
- model = field.remote_field.model if hasattr(field, 'remote_field') else field.related_field.model
- app_label = model._meta.app_label
- model_name = model._meta.object_name
- self.ajax_attrs = format_html('{0}', flatatt({
- 'data-app-label': app_label,
- 'data-model': model_name,
- 'data-ajax--url': reverse('jet:model_lookup'),
- 'data-queryset--lookup': self.lookup_kwarg
- }))
- if self.lookup_val is None:
- return []
- other_model = get_model_from_relation(field)
- if hasattr(field, 'rel'):
- rel_name = field.rel.get_related_field().name
- else:
- rel_name = other_model._meta.pk.name
- queryset = model._default_manager.filter(**{rel_name: self.lookup_val}).all()
- return [(x._get_pk_val(), smart_text(x)) for x in queryset]
- class DateRangeFilter(admin.filters.FieldListFilter):
- def __init__(self, field, request, params, model, model_admin, field_path):
- self.lookup_kwarg_gte = '{}__gte'.format(field_path)
- self.lookup_kwarg_lte = '{}__lte'.format(field_path)
- super(DateRangeFilter, self).__init__(
- field, request, params, model, model_admin, field_path)
- self.form = self.get_form(request)
- def choices(self, cl):
- yield {
- 'system_name': slugify(self.title),
- 'query_string': cl.get_query_string(
- {}, remove=[self.lookup_kwarg_gte, self.lookup_kwarg_lte]
- )
- }
- def expected_parameters(self):
- return [self.lookup_kwarg_gte, self.lookup_kwarg_lte]
- def queryset(self, request, queryset):
- if self.form.is_valid():
- validated_data = dict(self.form.cleaned_data.items())
- if validated_data:
- return queryset.filter(
- **self._make_query_filter(validated_data)
- )
- return queryset
- def _make_query_filter(self, validated_data):
- query_params = {}
- date_value_gte = validated_data.get(self.lookup_kwarg_gte, None)
- date_value_lte = validated_data.get(self.lookup_kwarg_lte, None)
- if date_value_gte:
- query_params['{0}__gte'.format(self.field_path)] = make_dt_aware(
- datetime.datetime.combine(date_value_gte, datetime.time.min)
- )
- if date_value_lte:
- query_params['{0}__lte'.format(self.field_path)] = make_dt_aware(
- datetime.datetime.combine(date_value_lte, datetime.time.max)
- )
- return query_params
- def get_template(self):
- return 'rangefilter/date_filter.html'
- template = property(get_template)
- def get_form(self, request):
- form_class = self._get_form_class()
- return form_class(self.used_parameters)
- def _get_form_class(self):
- fields = self._get_form_fields()
- form_class = type(
- str('DateRangeForm'),
- (forms.BaseForm,),
- {'base_fields': fields}
- )
- form_class.media = self._get_media()
- return form_class
- def _get_form_fields(self):
- return OrderedDict((
- (self.lookup_kwarg_gte, forms.DateField(
- label='',
- widget=AdminDateWidget(attrs={'placeholder': _('From date')}),
- localize=True,
- required=False
- )),
- (self.lookup_kwarg_lte, forms.DateField(
- label='',
- widget=AdminDateWidget(attrs={'placeholder': _('To date')}),
- localize=True,
- required=False
- )),
- ))
- @staticmethod
- def _get_media():
- css = [
- 'style.css',
- ]
- return forms.Media(
- css={'all': ['range_filter/css/%s' % path for path in css]}
- )
|