Ticket #1722: exclude_in_admin.diff

File exclude_in_admin.diff, 6.2 KB (added by anonymous, 13 years ago)
  • django/core/management.py

     
    897897                else:
    898898                    for fn in opts.admin.list_filter:
    899899                        try:
    900                             f = opts.get_field(fn)
     900                            f = opts.get_field(fn.lstrip('-'))
    901901                        except models.FieldDoesNotExist:
    902902                            e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
    903903
  • django/contrib/admin/filterspecs.py

     
    1111
    1212class FilterSpec(object):
    1313    filter_specs = []
    14     def __init__(self, f, request, params):
     14    def __init__(self, f, exclude_filter, request, params):
    1515        self.field = f
     16        self.exclude_filter = exclude_filter
    1617        self.params = params
    1718
    1819    def register(cls, test, factory):
    1920        cls.filter_specs.append( (test, factory) )
    2021    register = classmethod(register)
    2122
    22     def create(cls, f, request, params):
     23    def create(cls, f, exclude_filter, request, params):
    2324        for test, factory in cls.filter_specs:
    2425            if test(f):
    25                 return factory(f, request, params)
     26                return factory(f, exclude_filter, request, params)
    2627    create = classmethod(create)
    2728
    2829    def has_output(self):
     
    4243            for choice in self.choices(cl):
    4344                t.append('<li%s><a href="%s">%s</a></li>\n' % \
    4445                    ((choice['selected'] and ' class="selected"' or ''),
    45                      choice['query_string'] ,
     46                    (self.exclude_filter and join('-', choice['query_string']) or join('-', choice['query_string'])),
    4647                     choice['display']))
    4748            t.append('</ul>\n\n')
    4849        return "".join(t)
    4950
    5051class RelatedFilterSpec(FilterSpec):
    51     def __init__(self, f, request, params):
    52         super(RelatedFilterSpec, self).__init__(f, request, params)
     52    def __init__(self, f, exclude_filter, request, params):
     53        super(RelatedFilterSpec, self).__init__(f, exclude_filter, request, params)
    5354        if isinstance(f, models.ManyToManyField):
    5455            self.lookup_title = f.rel.to._meta.verbose_name
    5556        else:
    5657            self.lookup_title = f.verbose_name
    57         self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name)
     58        self.lookup_kwarg = '%s%s__%s__exact' % (self.exclude_filter and '-' or '', f.name, f.rel.to._meta.pk.name)
    5859        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    5960        self.lookup_choices = f.rel.to._default_manager.all()
    6061
     
    7778FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
    7879
    7980class ChoicesFilterSpec(FilterSpec):
    80     def __init__(self, f, request, params):
    81         super(ChoicesFilterSpec, self).__init__(f, request, params)
    82         self.lookup_kwarg = '%s__exact' % f.name
     81    def __init__(self, f, exclude_filter, request, params):
     82        super(ChoicesFilterSpec, self).__init__(f, exclude_filter, request, params)
     83        self.lookup_kwarg = '%s%s__exact' % (self.exclude_filter and '-' or '', f.name)
    8384        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    8485
    8586    def choices(self, cl):
     
    9495FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
    9596
    9697class DateFieldFilterSpec(FilterSpec):
    97     def __init__(self, f, request, params):
    98         super(DateFieldFilterSpec, self).__init__(f, request, params)
    99 
     98    def __init__(self, f, exclude_filter, request, params):
     99        super(DateFieldFilterSpec, self).__init__(f, exclude_filter, request, params)
     100       
    100101        self.field_generic = '%s__' % self.field.name
    101102
    102103        self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)])
     
    129130FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec)
    130131
    131132class BooleanFieldFilterSpec(FilterSpec):
    132     def __init__(self, f, request, params):
    133         super(BooleanFieldFilterSpec, self).__init__(f, request, params)
     133    def __init__(self, f, exclude_filter, request, params):
     134       
     135
     136
     137        super(BooleanFieldFilterSpec, self).__init__(f, exclude_filter, request, params)
    134138        self.lookup_kwarg = '%s__exact' % f.name
    135139        self.lookup_kwarg2 = '%s__isnull' % f.name
    136140        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
  • django/contrib/admin/views/main.py

     
    569569    def get_filters(self, request):
    570570        filter_specs = []
    571571        if self.lookup_opts.admin.list_filter and not self.opts.one_to_one_field:
    572             filter_fields = [self.lookup_opts.get_field(field_name) \
     572            filter_fields = [(self.lookup_opts.get_field(field_name.lstrip('-')), field_name.startswith('-')) \
    573573                              for field_name in self.lookup_opts.admin.list_filter]
    574             for f in filter_fields:
    575                 spec = FilterSpec.create(f, request, self.params)
     574            for f, exclude_filter in filter_fields:
     575                spec = FilterSpec.create(f, exclude_filter, request, self.params)
    576576                if spec and spec.has_output():
    577577                    filter_specs.append(spec)
    578578        return filter_specs, bool(filter_specs)
     
    669669                del lookup_params[i]
    670670
    671671        # Apply lookup parameters from the query string.
    672         qs = qs.filter(**lookup_params)
     672        filter_params={}
     673        exclude_params={}
     674        for k, v in lookup_params.iteritems():
     675            if k.startswith('-'):
     676               exclude_params[k.lstrip('-')]=v
     677            else:
     678               filter_params[k]=v
     679               
     680        qs = qs.filter(**filter_params)
     681        qs = qs.exclude(**exclude_params)
    673682
    674683        # Use select_related() if one of the list_display options is a field
    675684        # with a relationship.
Back to Top