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')
Beispiel #2
0
    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!')
Beispiel #3
0
 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)
Beispiel #4
0
    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!")
Beispiel #5
0
    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")
Beispiel #6
0
    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)
Beispiel #7
0
    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()
Beispiel #8
0
    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
Beispiel #10
0
    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