Beispiel #1
0
    def __init__(self, field, request, params, model, admin_view, field_path):
        self.field = field
        self.field_path = field_path
        # self.title = getattr(field, 'verbose_name', field_path)
        _field_parts = get_fields_from_path(model, field_path)
        _real_field = _field_parts[0]
        self.title = getattr(_real_field, 'verbose_name', field_path)
        self.context_params = {}

        super(FieldFilter, self).__init__(request, params, model, admin_view)

        for name, format in self.lookup_formats.items():
            p = format % field_path
            self.context_params["%s_name" % name] = FILTER_PREFIX + p
            if p in params:
                value = prepare_lookup_value(p, params.pop(p))
                self.used_params[p] = value
                self.context_params["%s_val" % name] = value
            else:
                self.context_params["%s_val" % name] = ''

        arr = map(lambda kv: setattr(self, 'lookup_' + kv[0], kv[1]),
                  self.context_params.items())
        if six.PY3:
            list(arr)
Beispiel #2
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([(smart_str(k)[len(FILTER_PREFIX):], v) for k, v in self.admin_view.params.items()
                              if smart_str(k).startswith(FILTER_PREFIX) and v != ''])
        for p_key, p_val in lookup_params.iteritems():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(remove=
                                                                           [k for k in self.request.GET.keys() if k.startswith(FILTER_PREFIX)])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation(
                        "Filtering by %s not allowed" % key)

        self.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(self.request, lookup_params,
                                       self.model, self)
                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, filter_manager.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, self.request, lookup_params,
                        self.model, self.admin_view, 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():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError, e:
                        new_qs = None
                        self.admin_view.message_user(_("<b>Filtering error:</b> %s") % e.messages[0], 'error')
                    if new_qs is not None:
                        queryset = new_qs


                    self.filter_specs.append(spec)
Beispiel #3
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([(smart_str(k)[len(FILTER_PREFIX):],v) for k,v in self.admin_view.params.items() \
            if smart_str(k).startswith(FILTER_PREFIX) and v != ''])
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(remove=\
                [k for k in self.request.GET.keys() if k.startswith(FILTER_PREFIX)])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" % key)

        self.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(self.request, lookup_params,
                        self.model, self)
                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, filter_manager.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, self.request, lookup_params,
                        self.model, self.admin_view, 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():
                    new_qs = spec.do_filte(queryset)
                    if new_qs is not None:
                        queryset = new_qs
                    self.filter_specs.append(spec)

        self.has_filters = bool(self.filter_specs)
        self.admin_view.filter_specs = self.filter_specs
        self.admin_view.used_filter_num = len(filter(lambda f: f.is_used, self.filter_specs))

        try:
            for key, value in lookup_params.items():
                use_distinct = (use_distinct or lookup_needs_distinct(self.opts, key))
        except FieldDoesNotExist, e:
            raise IncorrectLookupParameters(e)
Beispiel #4
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([(smart_text(k)[len(FILTER_PREFIX):], v) for k, v in self.admin_view.params.items()
                              if str(k).startswith(FILTER_PREFIX) and v != ''])
        for p_key, p_val in lookup_params.items():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(remove=
                                                                           [k for k in self.request.GET.keys() if k.startswith(FILTER_PREFIX)])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation(
                        "Filtering by %s not allowed" % key)

        self.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(self.request, lookup_params,
                                       self.model, self)
                else:
                    field_path = None
                    field_parts = []
                    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, filter_manager.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field_parts = get_fields_from_path(
                            self.model, field_path)
                        field = field_parts[-1]
                    spec = field_list_filter_class(
                        field, self.request, lookup_params,
                        self.model, self.admin_view, field_path=field_path)

                    if len(field_parts)>1:
                        # Add related model name to title
                        spec.title = "%s %s"%(field_parts[-2].name,spec.title)

                    # 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():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError as e:
                        new_qs = None
                        self.admin_view.message_user(_("<b>Filtering error:</b> %s") % e.messages[0], 'error')
                    if new_qs is not None:
                        queryset = new_qs

                self.filter_specs.append(spec)

        self.has_filters = bool(self.filter_specs)
        self.admin_view.filter_specs = self.filter_specs
        self.admin_view.used_filter_num = len(
            list(filter(lambda f: f.is_used, self.filter_specs)))

        try:
            for key, value in lookup_params.items():
                use_distinct = (
                    use_distinct or lookup_needs_distinct(self.opts, key))
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters(e)

        try:
            queryset = queryset.filter(**lookup_params)
        except (SuspiciousOperation, ImproperlyConfigured):
            raise
        except Exception as e:
            raise IncorrectLookupParameters(e)

        query = self.request.GET.get(SEARCH_VAR, '')

        # Apply keyword searches.
        def construct_search(field_name):
            if field_name.startswith('^'):
                return "%s__istartswith" % field_name[1:]
            elif field_name.startswith('='):
                return "%s__iexact" % field_name[1:]
            elif field_name.startswith('@'):
                return "%s__search" % field_name[1:]
            else:
                return "%s__icontains" % field_name

        if self.search_fields and query:
            orm_lookups = [construct_search(str(search_field))
                           for search_field in self.search_fields]
            for bit in query.split():
                or_queries = [models.Q(**{orm_lookup: bit})
                              for orm_lookup in orm_lookups]
                queryset = queryset.filter(reduce(operator.or_, or_queries))
            if not use_distinct:
                for search_spec in orm_lookups:
                    if lookup_needs_distinct(self.opts, search_spec):
                        use_distinct = True
                        break
            self.admin_view.search_query = query

        if use_distinct:
            return queryset.distinct()
        else:
            return queryset
Beispiel #5
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([
            (smart_str(k)[len(FILTER_PREFIX):], v)
            for k, v in self.admin_view.params.items()
            if smart_str(k).startswith(FILTER_PREFIX) and v != ''
        ])
        for p_key, p_val in lookup_params.items():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(
            remove=[
                k for k in self.request.GET.keys()
                if k.startswith(FILTER_PREFIX)
            ])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" %
                                              key)

        self.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(self.request, lookup_params, self.model,
                                       self)
                else:
                    field_path = None
                    field_parts = []
                    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, filter_manager.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field_parts = get_fields_from_path(
                            self.model, field_path)
                        field = field_parts[-1]
                    spec = field_list_filter_class(field,
                                                   self.request,
                                                   lookup_params,
                                                   self.model,
                                                   self.admin_view,
                                                   field_path=field_path)

                    if len(field_parts) > 1:
                        # Add related model name to title
                        spec.title = "%s %s" % (field_parts[-2].name,
                                                spec.title)

                    # 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():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError as e:
                        new_qs = None
                        self.admin_view.message_user(
                            _("<b>Filtering error:</b> %s") % e.messages[0],
                            'error')
                    if new_qs is not None:
                        queryset = new_qs

                    self.filter_specs.append(spec)

        self.has_filters = bool(self.filter_specs)
        self.admin_view.filter_specs = self.filter_specs
        obj = filter(lambda f: f.is_used, self.filter_specs)
        if six.PY3:
            obj = list(obj)
        self.admin_view.used_filter_num = len(obj)

        try:
            for key, value in lookup_params.items():
                use_distinct = (use_distinct
                                or lookup_needs_distinct(self.opts, key))
        except FieldDoesNotExist as e:
            raise IncorrectLookupParameters(e)

        try:
            queryset = queryset.filter(**lookup_params)
        except (SuspiciousOperation, ImproperlyConfigured):
            raise
        except Exception as e:
            raise IncorrectLookupParameters(e)

        query = self.request.GET.get(SEARCH_VAR, '')

        # Apply keyword searches.
        def construct_search(field_name):
            if field_name.startswith('^'):
                return "%s__istartswith" % field_name[1:]
            elif field_name.startswith('='):
                return "%s__iexact" % field_name[1:]
            elif field_name.startswith('@'):
                return "%s__search" % field_name[1:]
            else:
                return "%s__icontains" % field_name

        if self.search_fields and query:
            orm_lookups = [
                construct_search(str(search_field))
                for search_field in self.search_fields
            ]
            for bit in query.split():
                or_queries = [
                    models.Q(**{orm_lookup: bit}) for orm_lookup in orm_lookups
                ]
                queryset = queryset.filter(reduce(operator.or_, or_queries))
            if not use_distinct:
                for search_spec in orm_lookups:
                    if lookup_needs_distinct(self.opts, search_spec):
                        use_distinct = True
                        break
            self.admin_view.search_query = query

        if use_distinct:
            return queryset.distinct()
        else:
            return queryset
Beispiel #6
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([
            (smart_str(k)[len(FILTER_PREFIX):], v)
            for k, v in self.admin_view.params.items()
            if smart_str(k).startswith(FILTER_PREFIX) and v != ''
        ])
        for p_key, p_val in lookup_params.iteritems():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(
            remove=[
                k for k in self.request.GET.keys()
                if k.startswith(FILTER_PREFIX)
            ])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" %
                                              key)

        self.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(self.request, lookup_params, self.model,
                                       self)
                else:
                    field_path = None
                    field_parts = []
                    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, filter_manager.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        field_parts = get_fields_from_path(
                            self.model, field_path)
                        field = field_parts[-1]
                    spec = field_list_filter_class(field,
                                                   self.request,
                                                   lookup_params,
                                                   self.model,
                                                   self.admin_view,
                                                   field_path=field_path)

                    if len(field_parts) > 1:
                        # Add related model name to title
                        spec.title = "%s %s" % (field_parts[-2].name,
                                                spec.title)

                    # 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():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError, e:
                        new_qs = None
                        self.admin_view.message_user(
                            _("<b>Filtering error:</b> %s") % e.messages[0],
                            'error')
                    if new_qs is not None:
                        queryset = new_qs

                    self.filter_specs.append(spec)
Beispiel #7
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([
            (smart_str(k)[len(FILTER_PREFIX):], v)
            for k, v in self.admin_view.params.items()
            if smart_str(k).startswith(FILTER_PREFIX) and v != ''
        ])
        for p_key, p_val in lookup_params.iteritems():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        if not hasattr(self.admin_view, 'quickfilter'):
            self.admin_view.quickfilter = {}

        # for clean filters
        self.admin_view.quickfilter['has_query_param'] = bool(lookup_params)
        self.admin_view.quickfilter[
            'clean_query_url'] = self.admin_view.get_query_string(remove=[
                k for k in self.request.GET.keys()
                if k.startswith(FILTER_PREFIX)
            ])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" %
                                              key)

        self.filter_specs = []
        if self.list_quick_filter:
            for list_quick_filter in self.list_quick_filter:
                field_path = None
                field_order_by = None
                field_limit = None
                field_parts = []
                sort_key = None
                cache_config = None

                if type(list_quick_filter
                        ) == dict and 'field' in list_quick_filter:
                    field = list_quick_filter['field']
                    if 'order_by' in list_quick_filter:
                        field_order_by = list_quick_filter['order_by']
                    if 'limit' in list_quick_filter:
                        field_limit = list_quick_filter['limit']
                    if 'sort' in list_quick_filter and callable(
                            list_quick_filter['sort']):
                        sort_key = list_quick_filter['sort']
                    if 'cache' in list_quick_filter and type(
                            list_quick_filter) == dict:
                        cache_config = list_quick_filter['cache']

                else:
                    field = list_quick_filter  # This plugin only uses MultiselectFieldListFilter

                if not isinstance(field, models.Field):
                    field_path = field
                    field_parts = get_fields_from_path(self.model, field_path)
                    field = field_parts[-1]
                spec = QuickFilterMultiSelectFieldListFilter(
                    field,
                    self.request,
                    lookup_params,
                    self.model,
                    self.admin_view,
                    field_path=field_path,
                    field_order_by=field_order_by,
                    field_limit=field_limit,
                    sort_key=sort_key,
                    cache_config=cache_config)

                if len(field_parts) > 1:
                    spec.title = "%s %s" % (field_parts[-2].name, spec.title)

                # Check if we need to use distinct()
                use_distinct = True  #(use_distinct orlookup_needs_distinct(self.opts, field_path))
                if spec and spec.has_output():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError, e:
                        new_qs = None
                        self.admin_view.message_user(
                            u"<b>过滤器错误:</b> %s" % e.messages[0], 'error')
                    if new_qs is not None:
                        queryset = new_qs

                    self.filter_specs.append(spec)
Beispiel #8
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([(smart_str(k)[len(FILTER_PREFIX):], v) for k, v in self.admin_view.params.items() if smart_str(k).startswith(FILTER_PREFIX) and v != ''])
        for p_key, p_val in lookup_params.iteritems():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False
        
        if not hasattr(self.admin_view,'quickfilter'):
            self.admin_view.quickfilter = {}
 
        # for clean filters
        self.admin_view.quickfilter['has_query_param'] = bool(lookup_params)
        self.admin_view.quickfilter['clean_query_url'] = self.admin_view.get_query_string(remove=[k for k in self.request.GET.keys() if k.startswith(FILTER_PREFIX)])
 
        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" % key)
 
        self.filter_specs = []
        if self.list_quick_filter:
            for list_quick_filter in self.list_quick_filter:
                field_path = None
                field_order_by = None
                field_limit = None
                field_parts = []
                sort_key = None 
                cache_config = None
                
                if type(list_quick_filter)==dict and 'field' in list_quick_filter:
                    field = list_quick_filter['field']
                    if 'order_by' in list_quick_filter:
                        field_order_by = list_quick_filter['order_by']
                    if 'limit' in list_quick_filter:
                        field_limit = list_quick_filter['limit']
                    if 'sort' in list_quick_filter and callable(list_quick_filter['sort']):
                        sort_key = list_quick_filter['sort']
                    if 'cache' in list_quick_filter and type(list_quick_filter)==dict:
                        cache_config = list_quick_filter['cache']
                        
                else:        
                    field = list_quick_filter # This plugin only uses MultiselectFieldListFilter
                
                if not isinstance(field, models.Field):
                    field_path = field
                    field_parts = get_fields_from_path(self.model, field_path)
                    field = field_parts[-1]
                spec = QuickFilterMultiSelectFieldListFilter(field, self.request, lookup_params,self.model, self.admin_view, field_path=field_path,field_order_by=field_order_by,field_limit=field_limit,sort_key=sort_key,cache_config=cache_config)
                 
                if len(field_parts)>1:
                    spec.title = "%s %s"%(field_parts[-2].name,spec.title) 
                 
                # Check if we need to use distinct()
                use_distinct = True#(use_distinct orlookup_needs_distinct(self.opts, field_path))
                if spec and spec.has_output():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError, e:
                        new_qs = None
                        self.admin_view.message_user(u"<b>过滤器错误:</b> %s" % e.messages[0], 'error')
                    if new_qs is not None:
                        queryset = new_qs
 
                    self.filter_specs.append(spec)
Beispiel #9
0
    def get_list_queryset(self, queryset):
        if hasattr(self.admin_view, 'get_list_filter'):
            self.list_filter = self.admin_view.get_list_filter()
        if hasattr(self.admin_view, 'get_search_fields'):
            self.search_fields = self.admin_view.get_search_fields()
        lookup_params = dict([(smart_str(k)[len(FILTER_PREFIX):], v) for k, v in self.admin_view.params.items()
                              if smart_str(k).startswith(FILTER_PREFIX) and v != ''])
        for p_key, p_val in lookup_params.iteritems():
            if p_val == "False":
                lookup_params[p_key] = False
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(remove=
                                                                           [k for k in self.request.GET.keys() if k.startswith(FILTER_PREFIX)])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation(
                        "Filtering by %s not allowed" % key)

        self.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(self.request, lookup_params,
                                       self.model, self)
                else:
                    field_path = None
                    field_parts = []
                    where_parts = None
                    choices = None
                    title = None
                    if isinstance(list_filter, (tuple, list)):
                        # This is a custom FieldListFilter class for a given field.
                        field, field_list_filter_class, config = list_filter
                        if config:
                            if 'title' in config:
                                title = config['title']
                            if 'where_parts' in config:
                                where_parts = config['where_parts']
                            if 'choices' in config:
                                choices = config['choices']
                        if not field_list_filter_class:
                            field_list_filter_class = filter_manager.create
                    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, filter_manager.create
                    if not isinstance(field, models.Field):
                        field_path = field
                        try:
                            field_parts = get_fields_from_path(self.model, field_path)
                        except FieldDoesNotExist, e:
                            if not where_parts:
                                raise e
                            else:
                                field_parts = field_path.split('__')

                        field = field_parts[-1]

                    spec = field_list_filter_class(field, self.request, lookup_params, self.model, self.admin_view, field_path=field_path, title=title, where_parts=where_parts, external_choices=choices)
                    if not title and len(field_parts) > 1:
                        # Add related model name to title
                        spec.title = "%s %s" % (field_parts[-2].name, spec.title)

                    # Check if we need to use distinct()
                    if not where_parts:
                        use_distinct = (use_distinct or lookup_needs_distinct(self.opts, field_path))
                if spec and spec.has_output():
                    try:
                        new_qs = spec.do_filte(queryset)
                    except ValidationError, e:
                        new_qs = None
                        self.admin_view.message_user(_("<b>Filtering error:</b> %s") % e.messages[0], 'error')
                    if new_qs is not None:
                        queryset = new_qs

                    self.filter_specs.append(spec)
Beispiel #10
0
    def get_list_queryset(self, queryset):
        lookup_params = dict([
            (smart_str(k)[len(FILTER_PREFIX):], v)
            for k, v in self.admin_view.params.items()
            if smart_str(k).startswith(FILTER_PREFIX) and v != ''
        ])
        use_distinct = False

        # for clean filters
        self.admin_view.has_query_param = bool(lookup_params)
        self.admin_view.clean_query_url = self.admin_view.get_query_string(
            remove=[
                k for k in self.request.GET.keys()
                if k.startswith(FILTER_PREFIX)
            ])

        # Normalize the types of keys
        if not self.free_query_filter:
            for key, value in lookup_params.items():
                if not self.lookup_allowed(key, value):
                    raise SuspiciousOperation("Filtering by %s not allowed" %
                                              key)

        self.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(self.request, lookup_params, self.model,
                                       self)
                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, filter_manager.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,
                                                   self.request,
                                                   lookup_params,
                                                   self.model,
                                                   self.admin_view,
                                                   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():
                    new_qs = spec.do_filte(queryset)
                    if new_qs is not None:
                        queryset = new_qs
                    self.filter_specs.append(spec)

        self.has_filters = bool(self.filter_specs)
        self.admin_view.filter_specs = self.filter_specs
        self.admin_view.used_filter_num = len(
            filter(lambda f: f.is_used, self.filter_specs))

        try:
            for key, value in lookup_params.items():
                use_distinct = (use_distinct
                                or lookup_needs_distinct(self.opts, key))
        except FieldDoesNotExist, e:
            raise IncorrectLookupParameters(e)