def test_use_24_hour_time_format_en(self): field = DateTimeField() supported_custom_examples = [ '10/25/2006 2:30:59', '10/25/2006 2:30', '10/25/2006 14:30:59', '10/25/2006 14:30', ] for example in supported_custom_examples: try: result = field.to_python(example) self.assertIsInstance(result, datetime.datetime) except ValidationError: self.fail('Format of "{}" not recognized!'.format(example)) with self.assertRaises(ValidationError): field.to_python('invalid date string!') dt = datetime.datetime(year=2011, month=11, day=4, hour=23, minute=5, second=59) self.assertEqual( date_format(dt, 'DATETIME_FORMAT'), 'Nov. 4, 2011, 23:05:59') dt = datetime.datetime(year=2011, month=11, day=4, hour=2, minute=5, second=59) self.assertEqual( date_format(dt, 'SHORT_DATETIME_FORMAT'), '11/04/2011 2:05:59') t = datetime.time(hour=16, minute=2, second=25) self.assertEqual(time_format(t), '16:02:25')
def test_datetime_input_formats(self): field = DateTimeField() supported_custom_examples = [ '01/20/2020 9:30 AM', '01/20/2020 9:30:03 AM', '10/01/2020 11:30 PM', '10/01/2020 11:30:03 AM', ] for example in supported_custom_examples: result = field.to_python(example) self.assertIsInstance(result, datetime.datetime) with self.assertRaises(ValidationError): field.to_python('invalid date string!')
def to_python(self, value): try: date = dateutil.parser.parse(value) except ValueError: #Date utils couldn't figure it out. Let the default parser have a #swing at it and throw errors as necessary. date = value return DateTimeField.to_python(self, date)
def test_datetime_input_formats(self): update_en_us_date_formats() field = DateTimeField() supported_custom_examples = [ "01/20/2020 9:30 AM", "01/20/2020 9:30:03 AM", "10/01/2020 11:30 PM", "10/01/2020 11:30:03 AM", ] for example in supported_custom_examples: try: result = field.to_python(example) self.assertIsInstance(result, datetime.datetime) except ValidationError: self.fail('Format of "{}" not recognized!'.format(example)) with self.assertRaises(ValidationError): field.to_python("invalid date string!")
def test_use_24_hour_time_format(self): update_en_gb_date_formats() field = DateTimeField() supported_custom_examples = [ "25/10/2006 2:30:59", "25/10/2006 2:30", "25/10/2006 14:30:59", "25/10/2006 14:30", ] for example in supported_custom_examples: try: result = field.to_python(example) self.assertIsInstance(result, datetime.datetime) except ValidationError: self.fail('Format of "{}" not recognized!'.format(example)) with self.assertRaises(ValidationError): field.to_python("invalid date string!") dt = datetime.datetime(year=2011, month=11, day=4, hour=23, minute=5, second=59) self.assertEqual(date_format(dt, "DATETIME_FORMAT"), "4 November 2011 23:05:59") dt = datetime.datetime(year=2011, month=11, day=4, hour=2, minute=5, second=59) self.assertEqual(date_format(dt, "SHORT_DATETIME_FORMAT"), "04/11/2011 02:05") t = datetime.time(hour=16, minute=2, second=25) self.assertEqual(time_format(t), "16:02")
def __init__(self, *args, **kwargs): """Preparing form - it consists of dynamic fields, except ordering.""" self.custom_filter = kwargs.pop('custom_filter', None) self.custom_filters = kwargs.pop('custom_filters', None) self.request = kwargs.pop('request', None) self.model_admin = kwargs.pop('model_admin', None) self.new_query = kwargs.pop('new_query', None) super(CustomFilterForm, self).__init__(*args, **kwargs) if type(self.data) == dict: self.data = QueryDict(self.data) self.skip_validation = True self.params = args[0] if args else QueryDict('') all_fields = [f.replace('_enabled', '') for f in self.data if f.endswith('_enabled')] self.new_fields = [f for f in all_fields if f not in self.custom_filter.all_queries_names] if self.new_query: self.data['%s_enabled' % self.new_query] = 'on' self.new_fields.append(self.new_query) if isinstance(self.custom_filter.filter_ordering, list): ordering_choices = self.custom_filter.ordering_choices ordering_field = forms.MultipleChoiceField(required=False) else: widget = forms.Select(attrs={'class': 'single_ordering'}) ordering_choices = [('', '')] + self.custom_filter.ordering_choices ordering_field = forms.ChoiceField(widget=widget, required=False) self.fields['ordering'] = ordering_field self.fields['ordering'].choices = ordering_choices self.fields['ordering'].initial = self.custom_filter.filter_ordering if self.custom_filter.choices: self.fields[ADMINFILTERS_ADD_PARAM] = forms.ChoiceField(label=_(u'Add field to filter:'), widget=forms.Select(attrs={'class': 'add_adminfilters'}), required=False) self.fields[ADMINFILTERS_ADD_PARAM].choices = [('', '')] + self.custom_filter.choices if self.custom_filters: self.fields[ADMINFILTERS_LOAD_PARAM] = forms.ChoiceField(label=_(u'Load preset:'), widget=forms.Select(attrs={'class':'load_adminfilters'})) self.fields[ADMINFILTERS_LOAD_PARAM].choices = [('', '')] + [(cf.id, cf.verbose_name) for cf in self.custom_filters] self.field_rows = [] for query in self.custom_filter.bundled_queries.all(): query_instance = query.query_instance(None, {}, self.custom_filter.model, None) if query_instance: row = ['%s_enabled' % query_instance.parameter_name, '%s_criteria' % query_instance.parameter_name] self.fields['%s_enabled' % query_instance.parameter_name] = forms.BooleanField(label=query_instance.title.title(), initial=True, required=False, widget=forms.CheckboxInput(attrs={'class':'enable'})) query_criterias = [(p, t) for (p, t) in query_instance.lookups(None, self.custom_filter.model)] self.fields['%s_criteria' % query_instance.parameter_name] = forms.ChoiceField(choices=query_criterias, initial=query.value, required=False, widget=forms.Select(attrs={'class':'criteria'})) self.field_rows.append(row) for query in list(self.custom_filter.queries.all()) + self.new_fields: if not isinstance(query, CustomQuery): query = CustomQuery(custom_filter=self.custom_filter, field=query) field = DateTimeField() if query.model_field: row = ['%s_enabled' % query.field, '%s_criteria' % query.field] self.fields['%s_enabled' % query.field] = forms.BooleanField(label=query.field_verbose_name, initial=True, required=False, widget=forms.CheckboxInput(attrs={'class':'enable'})) if query.criterias: self.fields['%s_criteria' % query.field] = forms.ChoiceField(choices=query.criterias, initial=query.criteria, required=False, widget=forms.Select(attrs={'class':'criteria'})) if query.choices: attrs = {'class': 'value'} if query.is_multiple or len(self.params.getlist('%s_value' % query.field, None)) > 1: widget = forms.SelectMultiple(attrs=attrs) value_field = forms.MultipleChoiceField(choices=query.choices, initial=query.value, widget=widget) else: widget = forms.Select(attrs=attrs) value_field = forms.ChoiceField(choices=query.choices, initial=query.value, widget=widget) elif query.field_type in ['date', 'datetime']: if query.is_multiple: from datetime import datetime value = datetime.now() else: try: value = field.to_python(query.value) except ValidationError: value = field.to_python(query.value[:-7]) if query.field_type == 'date': value_field = forms.DateField(initial=value, widget=widgets.AdminDateWidget()) elif query.field_type == 'datetime': value_field = forms.DateTimeField(initial=value, widget=widgets.AdminSplitDateTime()) dwidget = forms.TextInput(attrs={'style': 'display: %s' % ('block' if query.criteria == 'days_ago' else 'none'), 'size': 5}) dfield = forms.CharField(initial=query.value, widget=dwidget, required=False) else: value_field = forms.CharField(initial=query.value, widget=forms.TextInput(attrs={'size':10})) if value_field: self.fields['%s_value' % query.field] = value_field row.append('%s_value' % query.field) if query.field_type in ['date', 'datetime', 'integer']: row.append('%s_start' % query.field) row.append('%s_end' % query.field) self.fields['%s_start' % query.field] = value_field self.fields['%s_end' % query.field] = value_field if query.field_type in ['date', 'datetime']: row.append('%s_dago' % query.field) self.fields['%s_dago' % query.field] = dfield if query.criteria == 'between': default_value = ['', ''] bvalue = getattr(query, 'field_value') or default_value self.initial['%s_start' % query.field] = field.to_python(bvalue[0]) if bvalue[0] else None self.initial['%s_end' % query.field] = field.to_python(bvalue[1]) if bvalue[1] else None self.initial['%s_dago' % query.field] = '' self.initial['%s_value' % query.field] = '' self.field_rows.append(row)
def save(self, *args, **kwargs): params = self.data if params.get('e'): return filter_ordering = params.getlist('ordering', None) if '' in filter_ordering: filter_ordering.remove('') self.custom_filter.filter_ordering = filter_ordering for query in self.custom_filter.bundled_queries.all(): query_instance = query.query_instance(None, {}, self.custom_filter.model, None) if params.get('%s_enabled' % query_instance.parameter_name, None): criteria = params.get('%s_criteria' % query_instance.parameter_name, None) query.field = query_instance.parameter_name query.value = criteria query.save() else: query.delete() for query in list(self.custom_filter.queries.all()) + self.new_fields: if not isinstance(query, CustomQuery): query = CustomQuery(custom_filter=self.custom_filter, field=query) if params.get('%s_enabled' % query.field, None): criteria = params.get('%s_criteria' % query.field, 'exact') query.criteria = criteria value = params.getlist('%s_value' % query.field, None) # some sort of hack to detect if we have multiple values if not query.is_multiple and not len(value): value = params.get('%s_value' % query.field, None) days_ago = params.get('%s_dago' % query.field, None) field = DateTimeField() if criteria == 'between': if query.field_type == 'date': start = params.get('%s_start' % query.field, '') end = params.get('%s_end' % query.field, '') else: start = field.to_python('%s %s' % (params.get('%s_start_0' % query.field, ''), params.get('%s_start_1' % query.field, ''))) end = field.to_python('%s %s' % (params.get('%s_end_0' % query.field, ''), params.get('%s_end_1' % query.field, ''))) query.is_multiple = True query.field_value = [str(start), str(end)] elif criteria in ('lt', 'gt') and query.field_type in ('date', 'datetime'): start = field.to_python('%s %s' % (params.get('%s_value_0' % query.field, ''), params.get('%s_value_1' % query.field, ''))) query.field_value = str(start) elif criteria == 'days_ago': query.field_value = days_ago elif criteria == 'this_week': value = None elif days_ago and not value and criteria not in ['this_year']: query.field_value = field.to_python('%s %s' % (params.get('%s_value_0' % query.field, ''), params.get('%s_value_1' % query.field, ''))) elif query.field_type == 'datetime' and criteria == 'exact': query.field_value = field.to_python('%s %s' % (params.get('%s_value_0' % query.field, ''), params.get('%s_value_1' % query.field, ''))) else: query.is_multiple = True if (isinstance(value, list) and len(value) > 1) else False query.field_value = value # some sort of hack to detect if we have multiple values if not query.is_multiple and isinstance(value, list) and len(value) == 1: query.value = value[0] query.save() else: query.delete() self.custom_filter.save()
def get_filter_params(self): """Preparing parameters for change list queryset, based on attached queries.""" filter_params = {} exclude_params = {} bundled_params = {} field = DateTimeField() for query in self.queries.all(): if query.model_field: key = query.field if query.criteria: # avoiding load of empty criteria dates_criterias = ['today', 'this_week', 'this_month', 'this_year', 'between', 'days_ago'] if query.criteria not in dates_criterias: if type(query.field_value) is list: if len(query.field_value) > 1: key += '__in' query.field_value = ','.join(query.field_value) if query.field_type in ('datetime', 'date'): field = DateTimeField() query.value = field.to_python(query.field_value) else: key += '__%s' % query.criteria elif type(query.field_value) is list and len(query.field_value) > 1 and query.criteria not in dates_criterias: if query.criteria != 'between': key += '__in' # preparing date-related criteria if query.criteria in ['today', 'this_week', 'this_month', 'this_year', 'days_ago']: date = datetime.datetime.now() value = None if query.criteria == 'today': value = date.strftime('%Y-%m-%d') if query.criteria == 'this_month': # we need to filter by current year to make sure we have only from this month, # not all records with month with given number filter_params[key + '__year'] = date.strftime('%Y') key += '__month' value = date.strftime('%m') if query.criteria == 'this_year': key += '__year' value = date.strftime('%Y') if query.criteria == 'this_week': date = datetime.date.today() start_week = date - datetime.timedelta(date.weekday()) end_week = start_week + datetime.timedelta(7) key += '__range' value = [start_week, end_week] filter_params[key] = value if query.criteria == 'days_ago': date = datetime.date.today() - datetime.timedelta(days=int(query.field_value)) del(filter_params[key]) filter_params[key + '__year'] = date.year filter_params[key + '__month'] = date.month filter_params[key + '__day'] = date.day elif query.criteria == 'between': start_value = query.field_value[0] end_value = query.field_value[0] if query.field_type in ('date', 'datetime'): start_value = field.to_python(query.field_value[0]) if start_value else start_value end_value = field.to_python(query.field_value[1]) if end_value else end_value if query.field_value[0]: filter_params['%s__gt' % key] = start_value if query.field_value[1]: filter_params['%s__lte' % key] = end_value elif query.criteria == '_notcontains': exclude_params[key + '__icontains'] = query.field_value elif query.criteria == 'not': exclude_params[key[:-5]] = query.field_value elif query.criteria == 'startswith': filter_params[key + '__startswith'] = query.field_value elif query.criteria == 'endswith': filter_params[key + '__endswith'] = query.field_value elif query.field_value: # avoiding load of empty filter value which causes database error if query.model_field.get_internal_type() == 'BooleanField': filter_params[key] = {'true': True, 'false': False}[query.field_value] else: if query.criteria in ('lt', 'gt'): if not key.endswith('__' + query.criteria): key = key + '__' + query.criteria filter_params[key] = query.field_value else: filter_params[key] = query.field_value if query.field_type in ('date', 'datetime') and query.field_value and query.criteria not in ('lt', 'gt'): date = field.to_python(query.field_value) # needed to cover case when field is datetime and time is not specified if not date.hour and not date.minute and not date.second: del(filter_params[key]) filter_params[query.field + '__year'] = date.year filter_params[query.field + '__month'] = date.month filter_params[query.field + '__day'] = date.day for query in self.bundled_queries.all(): bundled_params[query.field] = query.value return filter_params, exclude_params, bundled_params
def datetimetype(s): f = DateTimeField() try: return f.to_python(s) except ValidationError as e: raise argparse.ArgumentTypeError("Unrecognized datetime format") from e
def get_filter_params(self): """Preparing parameters for change list queryset, based on attached queries.""" filter_params = {} exclude_params = {} bundled_params = {} field = DateTimeField() for query in self.queries.all(): if query.model_field: key = query.field if query.criteria: # avoiding load of empty criteria dates_criterias = [ 'today', 'this_week', 'this_month', 'this_year', 'between', 'days_ago' ] if query.criteria not in dates_criterias: if type(query.field_value) is list: if len(query.field_value) > 1: key += '__in' query.field_value = ','.join(query.field_value) if query.field_type in ('datetime', 'date'): field = DateTimeField() query.value = field.to_python( query.field_value) else: key += '__%s' % query.criteria elif type(query.field_value) is list and len( query.field_value ) > 1 and query.criteria not in dates_criterias: if query.criteria != 'between': key += '__in' # preparing date-related criteria if query.criteria in [ 'today', 'this_week', 'this_month', 'this_year', 'days_ago' ]: date = datetime.datetime.now() value = None if query.criteria == 'today': value = date.strftime('%Y-%m-%d') if query.criteria == 'this_month': # we need to filter by current year to make sure we have only from this month, # not all records with month with given number filter_params[key + '__year'] = date.strftime('%Y') key += '__month' value = date.strftime('%m') if query.criteria == 'this_year': key += '__year' value = date.strftime('%Y') if query.criteria == 'this_week': date = datetime.date.today() start_week = date - datetime.timedelta( date.weekday()) end_week = start_week + datetime.timedelta(7) key += '__range' value = [start_week, end_week] filter_params[key] = value if query.criteria == 'days_ago': date = datetime.date.today() - datetime.timedelta( days=int(query.field_value)) del (filter_params[key]) filter_params[key + '__year'] = date.year filter_params[key + '__month'] = date.month filter_params[key + '__day'] = date.day elif query.criteria == 'between': start_value = query.field_value[0] end_value = query.field_value[0] if query.field_type in ('date', 'datetime'): start_value = field.to_python( query.field_value[0] ) if start_value else start_value end_value = field.to_python( query.field_value[1] ) if end_value else end_value if query.field_value[0]: filter_params['%s__gt' % key] = start_value if query.field_value[1]: filter_params['%s__lte' % key] = end_value elif query.criteria == '_notcontains': exclude_params[key + '__icontains'] = query.field_value elif query.criteria == 'not': exclude_params[key[:-5]] = query.field_value elif query.criteria == 'startswith': filter_params[key + '__startswith'] = query.field_value elif query.criteria == 'endswith': filter_params[key + '__endswith'] = query.field_value elif query.field_value: # avoiding load of empty filter value which causes database error if query.model_field.get_internal_type( ) == 'BooleanField': filter_params[key] = { 'true': True, 'false': False }[query.field_value] else: if query.criteria in ('lt', 'gt'): if not key.endswith('__' + query.criteria): key = key + '__' + query.criteria filter_params[key] = query.field_value else: filter_params[key] = query.field_value if query.field_type in ( 'date', 'datetime' ) and query.field_value and query.criteria not in ( 'lt', 'gt'): date = field.to_python(query.field_value) # needed to cover case when field is datetime and time is not specified if not date.hour and not date.minute and not date.second: del (filter_params[key]) filter_params[query.field + '__year'] = date.year filter_params[query.field + '__month'] = date.month filter_params[query.field + '__day'] = date.day for query in self.bundled_queries.all(): bundled_params[query.field] = query.value return filter_params, exclude_params, bundled_params