Ticket #3400: ticket-3400-against-newforms-admin-6477.diff

File ticket-3400-against-newforms-admin-6477.diff, 9.3 KB (added by Honza Král, 12 years ago)
  • django/contrib/admin/filterspecs.py

    diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py
    index 70dc29d..1ca10ed 100644
    a b import datetime 
    1313
    1414class FilterSpec(object):
    1515    filter_specs = []
    16     def __init__(self, f, request, params, model, model_admin):
     16    def __init__(self, f, request, params, model, model_admin, field_path=None):
    1717        self.field = f
    1818        self.params = params
     19        self.field_path = field_path or f.name
    1920
    2021    def register(cls, test, factory):
    2122        cls.filter_specs.append((test, factory))
    2223    register = classmethod(register)
    2324
    24     def create(cls, f, request, params, model, model_admin):
     25    def create(cls, f, request, params, model, model_admin, field_path=None):
    2526        for test, factory in cls.filter_specs:
    2627            if test(f):
    27                 return factory(f, request, params, model, model_admin)
     28                return factory(f, request, params, model, model_admin, field_path=field_path)
    2829    create = classmethod(create)
    2930
    3031    def has_output(self):
    class FilterSpec(object): 
    5051        return "".join(t)
    5152
    5253class RelatedFilterSpec(FilterSpec):
    53     def __init__(self, f, request, params, model, model_admin):
    54         super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin)
     54    def __init__(self, f, request, params, model, model_admin, field_path=None):
     55        super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
    5556        if isinstance(f, models.ManyToManyField):
    5657            self.lookup_title = f.rel.to._meta.verbose_name
    5758        else:
    5859            self.lookup_title = f.verbose_name
    59         self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name)
     60        self.lookup_kwarg = '%s__%s__exact' % (self.field_path, f.rel.to._meta.pk.name)
    6061        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    6162        self.lookup_choices = f.rel.to._default_manager.all()
    6263
    class RelatedFilterSpec(FilterSpec): 
    7980FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
    8081
    8182class ChoicesFilterSpec(FilterSpec):
    82     def __init__(self, f, request, params, model, model_admin):
    83         super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin)
    84         self.lookup_kwarg = '%s__exact' % f.name
     83    def __init__(self, f, request, params, model, model_admin, field_path=None):
     84        super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     85        self.lookup_kwarg = '%s__exact' % self.field_path
    8586        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    8687
    8788    def choices(self, cl):
    class ChoicesFilterSpec(FilterSpec): 
    9697FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
    9798
    9899class DateFieldFilterSpec(FilterSpec):
    99     def __init__(self, f, request, params, model, model_admin):
    100         super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin)
     100    def __init__(self, f, request, params, model, model_admin, field_path=None):
     101        super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
    101102
    102         self.field_generic = '%s__' % self.field.name
     103        self.field_generic = '%s__' % self.field_path
    103104
    104105        self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)])
    105106
    class DateFieldFilterSpec(FilterSpec): 
    109110
    110111        self.links = (
    111112            (_('Any date'), {}),
    112             (_('Today'), {'%s__year' % self.field.name: str(today.year),
    113                        '%s__month' % self.field.name: str(today.month),
    114                        '%s__day' % self.field.name: str(today.day)}),
    115             (_('Past 7 days'), {'%s__gte' % self.field.name: one_week_ago.strftime('%Y-%m-%d'),
    116                              '%s__lte' % f.name: today_str}),
    117             (_('This month'), {'%s__year' % self.field.name: str(today.year),
    118                              '%s__month' % f.name: str(today.month)}),
    119             (_('This year'), {'%s__year' % self.field.name: str(today.year)})
     113            (_('Today'), {'%s__year' % self.field_path: str(today.year),
     114                       '%s__month' % self.field_path: str(today.month),
     115                       '%s__day' % self.field_path: str(today.day)}),
     116            (_('Past 7 days'), {'%s__gte' % self.field_path: one_week_ago.strftime('%Y-%m-%d'),
     117                             '%s__lte' % self.field_path: today_str}),
     118            (_('This month'), {'%s__year' % self.field_path: str(today.year),
     119                             '%s__month' % self.field_path: str(today.month)}),
     120            (_('This year'), {'%s__year' % self.field_path: str(today.year)})
    120121        )
    121122
    122123    def title(self):
    class DateFieldFilterSpec(FilterSpec): 
    131132FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec)
    132133
    133134class BooleanFieldFilterSpec(FilterSpec):
    134     def __init__(self, f, request, params, model, model_admin):
    135         super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin)
    136         self.lookup_kwarg = '%s__exact' % f.name
    137         self.lookup_kwarg2 = '%s__isnull' % f.name
     135    def __init__(self, f, request, params, model, model_admin, field_path=None):
     136        super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     137        self.lookup_kwarg = '%s__exact' % self.field_path
     138        self.lookup_kwarg2 = '%s__isnull' % self.field_path
    138139        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    139140        self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None)
    140141
    FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f 
    157158# if a field is eligible to use the BooleanFieldFilterSpec, that'd be much
    158159# more appropriate, and the AllValuesFilterSpec won't get used for it.
    159160class AllValuesFilterSpec(FilterSpec):
    160     def __init__(self, f, request, params, model, model_admin):
    161         super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin)
    162         self.lookup_val = request.GET.get(f.name, None)
    163         self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
     161    def __init__(self, f, request, params, model, model_admin, field_path=None):
     162        super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     163        self.lookup_val = request.GET.get(self.field_path, None)
     164        #self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
     165        self.lookup_choices = model._default_manager.all().distinct().order_by(f.name).values(f.name)
    164166
    165167    def title(self):
    166168        return self.field.verbose_name
    167169
    168170    def choices(self, cl):
    169171        yield {'selected': self.lookup_val is None,
    170                'query_string': cl.get_query_string({}, [self.field.name]),
     172               'query_string': cl.get_query_string({}, [self.field_path]),
    171173               'display': _('All')}
    172174        for val in self.lookup_choices:
    173175            val = smart_unicode(val[self.field.name])
    174176            yield {'selected': self.lookup_val == val,
    175                    'query_string': cl.get_query_string({self.field.name: val}),
     177                   'query_string': cl.get_query_string({self.field_path: val}),
    176178                   'display': val}
    177179FilterSpec.register(lambda f: True, AllValuesFilterSpec)
  • django/contrib/admin/views/main.py

    diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
    index 01e659a..e3d286d 100644
    a b from django.db.models.query import handle_legacy_orderlist, QuerySet 
    1010from django.http import Http404
    1111from django.utils.encoding import force_unicode, smart_str
    1212from django.utils.translation import ugettext
     13from django.db.models.query import LOOKUP_SEPARATOR
    1314import operator
    1415
    1516try:
    class ChangeList(object): 
    153154    def get_filters(self, request):
    154155        filter_specs = []
    155156        if self.list_filter and not self.opts.one_to_one_field:
    156             filter_fields = [self.lookup_opts.get_field(field_name) for field_name in self.list_filter]
    157             for f in filter_fields:
    158                 spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin)
     157            lookup_opts = self.lookup_opts
     158            for filter_name in self.list_filter:
     159                if LOOKUP_SEPARATOR in filter_name:
     160                    f = None
     161                    model = self.model
     162                    path = filter_name.split(LOOKUP_SEPARATOR)
     163                    for field_name in path[:-1]:
     164                        f = model._meta.get_field(field_name)
     165                        model = f.rel.to
     166                    f = model._meta.get_field(path[-1])
     167                    spec = FilterSpec.create(f, request, self.params, model, self.model_admin, field_path=filter_name)
     168                else:
     169                    f = lookup_opts.get_field(filter_name)
     170                    spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin)
    159171                if spec and spec.has_output():
    160172                    filter_specs.append(spec)
    161173        return filter_specs, bool(filter_specs)
Back to Top