Example #1
0
    def choices(self, cl):
        for c in super().choices(cl):
            # alter 'selected' test for empty option as default implementation
            # does not check actual value of the argument
            if c['display'] == self.empty_value_display:
                c['selected'] = (
                    self.lookup_val_isnull is not None and
                    prepare_lookup_value(
                        self.lookup_kwarg_isnull, self.lookup_val_isnull
                    )
                )

                # list 'any' option before 'none'
                yield {
                    'selected': (
                        self.lookup_val_isnull is not None and
                        not c['selected']
                    ),
                    'query_string': cl.get_query_string(
                        {self.lookup_kwarg_isnull: 'False'},
                        [self.lookup_kwarg, self.lookup_kwarg_isnull]
                    ),
                    'display': _('Any'),
                }
            yield c
Example #2
0
    def get_filtered_queryset(self, qs):
        """ CUSTOM """

        query_string = self.GET.get('query_string', None)
        qset = Q()
        if query_string:
            for j, item2 in enumerate(query_string.split("|")):  # OR
                filters = {}
                for item in item2.split(":"):  # AND
                    k, v = item.split("=")
                    VALUE = smart_text(v)
                    if VALUE == 'TRUE':
                        VALUE = True
                    elif VALUE == 'FALSE':
                        VALUE = False
                    elif 'None' in VALUE:
                        VALUE = False
                    if k != "_to_field":
                        filters[smart_text(k)] = prepare_lookup_value(
                            smart_text(k), VALUE)
                qset |= Q(**filters)
        try:
            qs = qs.filter(qset)
        except:
            qs = qs.none()
        return qs
Example #3
0
 def __init__(self, request, params, model, model_admin):
     self.title = self.attribute_name
     super().__init__(request, params, model, model_admin)
     for p in self.expected_parameters():
         if p in params:
             value = params.pop(p)
             self.used_parameters[p] = prepare_lookup_value(p, value)
Example #4
0
    def get_filters(self, request):
        lookup_params = self.get_filters_params()
        use_distinct = False

        for key, value in lookup_params.items():
            if not self.lookup_allowed(key, value):
                raise DisallowedModelAdminLookup(
                    "Filtering by %s not allowed" % key)

        filter_specs = []
        if self.list_filter:
            for list_filter in self.list_filter:
                if callable(list_filter):
                    # This is simply a custom list filter class.
                    spec = list_filter(request, lookup_params, self.model,
                                       self.model_admin)
                else:
                    field_path = None
                    if isinstance(list_filter, (tuple, list)):
                        # This is a custom FieldListFilter class for a given
                        # field.
                        field, field_list_filter_class = list_filter
                    else:
                        # This is simply a field name, so use the default
                        # FieldListFilter class that has been registered for
                        # the type of the given field.
                        field = list_filter
                        field_list_filter_class = FieldListFilter.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field = get_fields_from_path(self.model,
                                                     field_path)[-1]
                    spec = field_list_filter_class(field,
                                                   request,
                                                   lookup_params,
                                                   self.model,
                                                   self.model_admin,
                                                   field_path=field_path)

                    # Check if we need to use distinct()
                    use_distinct = (use_distinct or lookup_needs_distinct(
                        self.opts, field_path))
                if spec and spec.has_output():
                    filter_specs.append(spec)

        # At this point, all the parameters used by the various ListFilters
        # have been removed from lookup_params, which now only contains other
        # parameters passed via the query string. We now loop through the
        # remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in lookup_params.items():
                lookup_params[key] = prepare_lookup_value(key, value)
                use_distinct = (use_distinct
                                or lookup_needs_distinct(self.opts, key))
            return (filter_specs, bool(filter_specs), lookup_params,
                    use_distinct)
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters from e
Example #5
0
    def get_filters(self, request):
        lookup_params = self.get_filters_params()
        use_distinct = False

        # Normalize the types of keys
        for key, value in lookup_params.items():
            if not isinstance(key, str):
                # 'key' will be used as a keyword argument later, so Python
                # requires it to be a string.
                del lookup_params[key]
                lookup_params[force_str(key)] = value

            if not self.model_admin.lookup_allowed(key, value):
                raise DisallowedModelAdminLookup("Filtering by %s not allowed" % key)

        filter_specs = []
        if self.list_filter:
            for list_filter in self.list_filter:
                if callable(list_filter):
                    # This is simply a custom list filter class.
                    spec = list_filter(request, lookup_params,
                                       self.model, self.model_admin)
                else:
                    field_path = None
                    if isinstance(list_filter, (tuple, list)):
                        # This is a custom FieldListFilter class for a given field.
                        field, field_list_filter_class = list_filter
                    else:
                        # This is simply a field name, so use the default
                        # FieldListFilter class that has been registered for
                        # the type of the given field.
                        field, field_list_filter_class = list_filter, FieldListFilter.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field = get_fields_from_path(self.model, field_path)[-1]
                    spec = field_list_filter_class(field, request, lookup_params,
                                                   self.model, self.model_admin,
                                                   field_path=field_path)
                    # Check if we need to use distinct()
                    use_distinct = (use_distinct or
                                    lookup_needs_distinct(self.lookup_opts,
                                                          field_path))
                if spec and spec.has_output():
                    filter_specs.append(spec)

        # At this point, all the parameters used by the various ListFilters
        # have been removed from lookup_params, which now only contains other
        # parameters passed via the query string. We now loop through the
        # remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in lookup_params.items():
                lookup_params[key] = prepare_lookup_value(key, value)
                use_distinct = (use_distinct or
                                lookup_needs_distinct(self.lookup_opts, key))
            return filter_specs, bool(filter_specs), lookup_params, use_distinct
        except FieldDoesNotExist as e:
            six.reraise(IncorrectLookupParameters, IncorrectLookupParameters(e), sys.exc_info()[2])
Example #6
0
 def __init__(self, field, request, params, model, model_admin, field_path):
     self.field = field
     self.field_path = field_path
     self.title = getattr(field, 'verbose_name', field_path)
     super().__init__(request, params, model, model_admin)
     for p in self.expected_parameters():
         if p in params:
             value = params.pop(p)
             self.used_parameters[p] = prepare_lookup_value(p, value)
Example #7
0
 def __init__(self, request, params, model, model_admin):
     self.title = "Advanced Search"
     super().__init__(request, params, model, model_admin)
     for p in self.expected_parameters():
         if p in params:
             value = params.pop(p)
             if value != None and value != '':
                 self.used_parameters[p] = prepare_lookup_value(
                     p, value)
Example #8
0
 def __init__(self, field, request, params, model, model_admin, field_path):
     self.field = field
     self.field_path = field_path
     self.title = getattr(field, 'verbose_name', field_path)
     super().__init__(request, params, model, model_admin)
     for p in self.expected_parameters():
         if p in params:
             value = params.pop(p)
             self.used_parameters[p] = prepare_lookup_value(p, value)
    def get_filtered_queryset(self, qs):
        filters = {}
        query_string = self.GET.get('query_string', None)

        if query_string:
            for item in query_string.split(":"):
                k, v = item.split("=")
                if k != "_to_field":
                    filters[smart_text(k)] = prepare_lookup_value(smart_text(k), smart_text(v))
        return qs.filter(**filters)
Example #10
0
    def get_filtered_queryset(self, qs):
        filters = {}
        query_string = self.GET.get('query_string', None)

        if query_string:
            for item in query_string.split(":"):
                k, v = item.split("=")
                if k != "_to_field":
                    filters[smart_text(k)] = prepare_lookup_value(smart_text(k), smart_text(v))
        return qs.filter(**filters)
Example #11
0
 def __init__(self, field, request, params, model, model_admin,
              field_path):
     super().__init__(field, request, params, model, model_admin,
                      field_path)
     self.lookup_kwarg = field_path.replace('__id__exact', '')
     self.params = dict(request.GET.items())
     for p in self.expected_parameters():
         if p in params:
             value = params.pop(p)
             self.used_parameters[p] = prepare_lookup_value(p, value)
     self.form = self.get_form(request, field, field_path, model)
Example #12
0
 def field_choices(self, field, request, model_admin):
     filtered_field = self.field_path
     limit_choices_to = {
         param.replace(f"{filtered_field}__", "", 1):
         prepare_lookup_value(param, value)
         for (param, value) in request.GET.items() if any(
             param.startswith(f"{filtered_field}__{field}")
             for field in fields)
     }
     return field.get_choices(include_blank=False,
                              limit_choices_to=limit_choices_to)
Example #13
0
    def get_filters(self, request):
        lookup_params = self.get_filters_params()
        use_distinct = False

        for key, value in lookup_params.items():
            if not self.model_admin.lookup_allowed(key, value):
                raise DisallowedModelAdminLookup("Filtering by %s not allowed" % key)

        filter_specs = []
        if self.list_filter:
            for list_filter in self.list_filter:
                if callable(list_filter):
                    # This is simply a custom list filter class.
                    spec = list_filter(request, lookup_params, self.model, self.model_admin)
                else:
                    field_path = None
                    if isinstance(list_filter, (tuple, list)):
                        # This is a custom FieldListFilter class for a given field.
                        field, field_list_filter_class = list_filter
                    else:
                        # This is simply a field name, so use the default
                        # FieldListFilter class that has been registered for
                        # the type of the given field.
                        field, field_list_filter_class = list_filter, FieldListFilter.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field = get_fields_from_path(self.model, field_path)[-1]

                    lookup_params_count = len(lookup_params)
                    spec = field_list_filter_class(
                        field, request, lookup_params,
                        self.model, self.model_admin, field_path=field_path
                    )
                    # field_list_filter_class removes any lookup_params it
                    # processes. If that happened, check if distinct() is
                    # needed to remove duplicate results.
                    if lookup_params_count > len(lookup_params):
                        use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path)
                if spec and spec.has_output():
                    filter_specs.append(spec)

        # At this point, all the parameters used by the various ListFilters
        # have been removed from lookup_params, which now only contains other
        # parameters passed via the query string. We now loop through the
        # remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in lookup_params.items():
                lookup_params[key] = prepare_lookup_value(key, value)
                use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key)
            return filter_specs, bool(filter_specs), lookup_params, use_distinct
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters(e) from e
Example #14
0
    def get_filters(self):
        params = dict(self.request.GET.items())
        opts = self.model._meta
        use_distinct = False
        list_filters = self.get_list_filters()
        new_params = {}
        has_filters = False

        # Normalize the types of keys
        list_names = [f if isinstance(f, str) else f.parameter_name for f in list_filters]
        for key, value in params.items():
            # ignore keys not in list_filters
            if key.startswith(tuple(list_names)):
                new_params[force_str(key)] = value

        has_filters = bool(new_params)
        filter_specs = []
        for list_filter in list_filters:
            if callable(list_filter):
                # This is simply a custom list filter class.
                spec = list_filter(self.request, new_params, self.model, None)
            else:
                field_path = None
                if isinstance(list_filter, (tuple, list)):
                    # Custom FieldListFilter class for a given field.
                    field, field_list_filter_class = list_filter
                else:
                    # Field name, so use the default registered FieldListFilter
                    field, field_list_filter_class = list_filter, FieldListFilter.create

                if not isinstance(field, models.Field):
                    field_path = field
                    field = get_fields_from_path(self.model, field_path)[-1]
                model_admin = admin.ModelAdmin(self.model, admin.site)
                spec = field_list_filter_class(field, self.request, new_params, self.model, model_admin, field_path=field_path)
                # Check if we need to use distinct()
                use_distinct = (use_distinct or lookup_needs_distinct(opts, field_path))
            if spec and spec.has_output():
                filter_specs.append(spec)

        # All the parameters used by the various ListFilters have been removed
        # lookup_params, now only contains other parameters passed via the query string.
        # We now loop through the remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in new_params.items():
                new_params[key] = prepare_lookup_value(key, value)
                use_distinct = (use_distinct or lookup_needs_distinct(opts, key))
            return filter_specs, has_filters, use_distinct
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters from e
        def __init__(self, field, request, params, model, model_admin, field_path):
            super().__init__(field, request, params, model, model_admin, field_path)
            self.lookup_kwarg = field_path.replace('__id__exact', '')
            self.params = dict(request.GET.items())
            for p in self.expected_parameters():
                if p in params:
                    value = params.pop(p)
                    self.used_parameters[p] = prepare_lookup_value(p, value)

            autocomplete_fields = getattr(site._registry.get(model), 'autocomplete_fields', None)
            if not autocomplete_fields or not autocomplete_fields.get(field_path):
                raise NotImplementedError("You must setup autocomplete fields")

            self.form = self.get_form(request, field, field_path, model)
Example #16
0
 def choices(self, cl):
     yield {
         'selected': self.value() is None,
         'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
         'display': _('All'),
     }
     for lookup, title in self.lookup_choices:
         yield {
             'selected': self.value() == prepare_lookup_value(self.lookup_kwarg, lookup),
             'query_string': cl.get_query_string({
                 self.lookup_kwarg: lookup,
             }, []),
             'display': title,
         }
Example #17
0
 def choices(self, cl):
     yield {
         'selected': self.value() is None,
         'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
         'display': _('All'),
     }
     for lookup, title in self.lookup_choices:
         yield {
             'selected': self.value() == prepare_lookup_value(self.lookup_kwarg, lookup),
             'query_string': cl.get_query_string({
                 self.lookup_kwarg: lookup,
             }, []),
             'display': title,
         }
Example #18
0
    def get(self, request, *args, **kwargs):
        """
        Return a JsonResponse with search results of the form:
        {
            results: [{id: "123", text: "foo"}],
            pagination: {more: true}
        }
        """
        app_label = request.GET['cool_app_label']
        model_name = request.GET['cool_model_name']
        limit_choices_to = request.GET.get('cool_limit_choices_to', None)
        to_field_name = request.GET.get('cool_to_field_name', 'pk')
        term = request.GET.get('term', '')

        if not self.has_perm(request, app_label, model_name):
            return JsonResponse({'error': '403 Forbidden'}, status=403)
        try:
            self.model = apps.get_model(app_label, model_name)
        except LookupError:
            return JsonResponse({'error': '403 Forbidden'}, status=403)

        queryset = self.get_queryset()

        filters = dict()
        if limit_choices_to:
            for key, value in parse_qsl(limit_choices_to):
                filters[key] = prepare_lookup_value(key, value)
        if filters:
            queryset = queryset.filter(**filters)

        get_search_fields = getattr(self.model, 'get_search_fields')
        search_fields = None
        if get_search_fields and callable(get_search_fields):
            search_fields = get_search_fields()
        if not search_fields:
            raise Http404('%s must have get_search_fields for the autocomplete_view.' % type(self.model).__name__)
        queryset, search_use_distinct = get_search_results(queryset, term, search_fields, self.model)
        if search_use_distinct:
            queryset = queryset.distinct()
        context = self.get_context_data(object_list=queryset)
        return JsonResponse({
            'results': [
                {'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
                for obj in context['object_list']
            ],
            'pagination': {'more': context['page_obj'].has_next()},
        })
Example #19
0
    _take_priority_index = 0

    def __init__(self, field, request, params, model, model_admin, field_path):
        self.field = field
        self.field_path = field_path
        self.title = getattr(field, 'verbose_name', field_path)
<<<<<<< HEAD
        super(FieldListFilter, self).__init__(
            request, params, model, model_admin)
=======
        super().__init__(request, params, model, model_admin)
>>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435
        for p in self.expected_parameters():
            if p in params:
                value = params.pop(p)
                self.used_parameters[p] = prepare_lookup_value(p, value)

    def has_output(self):
        return True

    def queryset(self, request, queryset):
        try:
            return queryset.filter(**self.used_parameters)
        except (ValueError, ValidationError) as e:
            # Fields may raise a ValueError or ValidationError when converting
            # the parameters to the correct type.
            raise IncorrectLookupParameters(e)

    @classmethod
    def register(cls, test, list_filter_class, take_priority=False):
        if take_priority:
Example #20
0
    def get_filters(self, request):
        lookup_params = self.get_filters_params()
        use_distinct = False

        for key, value in lookup_params.items():
            if not self.model_admin.lookup_allowed(key, value):
                raise DisallowedModelAdminLookup("Filtering by %s not allowed" % key)

        filter_specs = []
        for list_filter in self.list_filter:
            if callable(list_filter):
                # This is simply a custom list filter class.
                spec = list_filter(request, lookup_params, self.model, self.model_admin)
            else:
                field_path = None
                if isinstance(list_filter, (tuple, list)):
                    # This is a custom FieldListFilter class for a given field.
                    field, field_list_filter_class = list_filter
                else:
                    # This is simply a field name, so use the default
                    # FieldListFilter class that has been registered for the
                    # type of the given field.
                    field, field_list_filter_class = list_filter, FieldListFilter.create
                if not isinstance(field, models.Field):
                    field_path = field
                    field = get_fields_from_path(self.model, field_path)[-1]

                lookup_params_count = len(lookup_params)
                spec = field_list_filter_class(
                    field, request, lookup_params,
                    self.model, self.model_admin, field_path=field_path,
                )
                # field_list_filter_class removes any lookup_params it
                # processes. If that happened, check if distinct() is needed to
                # remove duplicate results.
                if lookup_params_count > len(lookup_params):
                    use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path)
            if spec and spec.has_output():
                filter_specs.append(spec)

        if self.date_hierarchy:
            # Create bounded lookup parameters so that the query is more
            # efficient.
            year = lookup_params.pop('%s__year' % self.date_hierarchy, None)
            if year is not None:
                month = lookup_params.pop('%s__month' % self.date_hierarchy, None)
                day = lookup_params.pop('%s__day' % self.date_hierarchy, None)
                try:
                    from_date = datetime(
                        int(year),
                        int(month if month is not None else 1),
                        int(day if day is not None else 1),
                    )
                except ValueError as e:
                    raise IncorrectLookupParameters(e) from e
                if settings.USE_TZ:
                    from_date = make_aware(from_date)
                if day:
                    to_date = from_date + timedelta(days=1)
                elif month:
                    # In this branch, from_date will always be the first of a
                    # month, so advancing 32 days gives the next month.
                    to_date = (from_date + timedelta(days=32)).replace(day=1)
                else:
                    to_date = from_date.replace(year=from_date.year + 1)
                lookup_params.update({
                    '%s__gte' % self.date_hierarchy: from_date,
                    '%s__lt' % self.date_hierarchy: to_date,
                })

        # At this point, all the parameters used by the various ListFilters
        # have been removed from lookup_params, which now only contains other
        # parameters passed via the query string. We now loop through the
        # remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in lookup_params.items():
                lookup_params[key] = prepare_lookup_value(key, value)
                use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key)
            return filter_specs, bool(filter_specs), lookup_params, use_distinct
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters(e) from e
Example #21
0
    def get_filters(self, request):
        lookup_params = self.get_filters_params()
        use_distinct = False

        for key, value in lookup_params.items():
            if not self.model_admin.lookup_allowed(key, value):
                raise DisallowedModelAdminLookup(
                    "Filtering by %s not allowed" % key)

        filter_specs = []
        for list_filter in self.list_filter:
            if callable(list_filter):
                # This is simply a custom list filter class.
                spec = list_filter(request, lookup_params, self.model,
                                   self.model_admin)
            else:
                field_path = None
                if isinstance(list_filter, (tuple, list)):
                    # This is a custom FieldListFilter class for a given field.
                    field, field_list_filter_class = list_filter
                else:
                    # This is simply a field name, so use the default
                    # FieldListFilter class that has been registered for the
                    # type of the given field.
                    field, field_list_filter_class = list_filter, FieldListFilter.create
                if not isinstance(field, models.Field):
                    field_path = field
                    field = get_fields_from_path(self.model, field_path)[-1]

                lookup_params_count = len(lookup_params)
                spec = field_list_filter_class(
                    field,
                    request,
                    lookup_params,
                    self.model,
                    self.model_admin,
                    field_path=field_path,
                )
                # field_list_filter_class removes any lookup_params it
                # processes. If that happened, check if distinct() is needed to
                # remove duplicate results.
                if lookup_params_count > len(lookup_params):
                    use_distinct = use_distinct or lookup_needs_distinct(
                        self.lookup_opts, field_path)
            if spec and spec.has_output():
                filter_specs.append(spec)

        if self.date_hierarchy:
            # Create bounded lookup parameters so that the query is more
            # efficient.
            year = lookup_params.pop('%s__year' % self.date_hierarchy, None)
            if year is not None:
                month = lookup_params.pop('%s__month' % self.date_hierarchy,
                                          None)
                day = lookup_params.pop('%s__day' % self.date_hierarchy, None)
                try:
                    from_date = datetime(
                        int(year),
                        int(month if month is not None else 1),
                        int(day if day is not None else 1),
                    )
                except ValueError as e:
                    raise IncorrectLookupParameters(e) from e
                if settings.USE_TZ:
                    from_date = make_aware(from_date)
                if day:
                    to_date = from_date + timedelta(days=1)
                elif month:
                    # In this branch, from_date will always be the first of a
                    # month, so advancing 32 days gives the next month.
                    to_date = (from_date + timedelta(days=32)).replace(day=1)
                else:
                    to_date = from_date.replace(year=from_date.year + 1)
                lookup_params.update({
                    '%s__gte' % self.date_hierarchy: from_date,
                    '%s__lt' % self.date_hierarchy: to_date,
                })

        # At this point, all the parameters used by the various ListFilters
        # have been removed from lookup_params, which now only contains other
        # parameters passed via the query string. We now loop through the
        # remaining parameters both to ensure that all the parameters are valid
        # fields and to determine if at least one of them needs distinct(). If
        # the lookup parameters aren't real fields, then bail out.
        try:
            for key, value in lookup_params.items():
                lookup_params[key] = prepare_lookup_value(key, value)
                use_distinct = use_distinct or lookup_needs_distinct(
                    self.lookup_opts, key)
            return filter_specs, bool(
                filter_specs), lookup_params, use_distinct
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters(e) from e
Example #22
0
"""