Ticket #3400: 3400-against-9646.patch

File 3400-against-9646.patch, 9.8 KB (added by Vitek Pliska, 11 years ago)

Quick update for trunk [9646]. Works wih 1.0.2 too

  • django/contrib/admin/filterspecs.py

    diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py
    index 97f4cb2..c9c3cb0 100644
    a b import datetime 
    1515
    1616class FilterSpec(object):
    1717    filter_specs = []
    18     def __init__(self, f, request, params, model, model_admin):
     18    def __init__(self, f, request, params, model, model_admin, field_path=None):
    1919        self.field = f
    2020        self.params = params
     21        self.field_path = field_path or f.name
    2122
    2223    def register(cls, test, factory):
    2324        cls.filter_specs.append((test, factory))
    2425    register = classmethod(register)
    2526
    26     def create(cls, f, request, params, model, model_admin):
     27    def create(cls, f, request, params, model, model_admin, field_path=None):
    2728        for test, factory in cls.filter_specs:
    2829            if test(f):
    29                 return factory(f, request, params, model, model_admin)
     30                return factory(f, request, params, model, model_admin, field_path=field_path)
    3031    create = classmethod(create)
    3132
    3233    def has_output(self):
    class FilterSpec(object): 
    5253        return mark_safe("".join(t))
    5354
    5455class RelatedFilterSpec(FilterSpec):
    55     def __init__(self, f, request, params, model, model_admin):
    56         super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin)
     56    def __init__(self, f, request, params, model, model_admin, field_path=None):
     57        super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
    5758        if isinstance(f, models.ManyToManyField):
    5859            self.lookup_title = f.rel.to._meta.verbose_name
    5960        else:
    6061            self.lookup_title = f.verbose_name
    61         self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name)
     62        self.lookup_kwarg = '%s__%s__exact' % (self.field_path, f.rel.to._meta.pk.name)
    6263        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    6364        self.lookup_choices = f.get_choices(include_blank=False)
    6465
    class RelatedFilterSpec(FilterSpec): 
    8081FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
    8182
    8283class ChoicesFilterSpec(FilterSpec):
    83     def __init__(self, f, request, params, model, model_admin):
    84         super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin)
    85         self.lookup_kwarg = '%s__exact' % f.name
     84    def __init__(self, f, request, params, model, model_admin, field_path=None):
     85        super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     86        self.lookup_kwarg = '%s__exact' % self.field_path
    8687        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    8788
    8889    def choices(self, cl):
    class ChoicesFilterSpec(FilterSpec): 
    9798FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
    9899
    99100class DateFieldFilterSpec(FilterSpec):
    100     def __init__(self, f, request, params, model, model_admin):
    101         super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin)
     101    def __init__(self, f, request, params, model, model_admin, field_path=None):
     102        super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
    102103
    103         self.field_generic = '%s__' % self.field.name
     104        self.field_generic = '%s__' % self.field_path
    104105
    105106        self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)])
    106107
    class DateFieldFilterSpec(FilterSpec): 
    110111
    111112        self.links = (
    112113            (_('Any date'), {}),
    113             (_('Today'), {'%s__year' % self.field.name: str(today.year),
    114                        '%s__month' % self.field.name: str(today.month),
    115                        '%s__day' % self.field.name: str(today.day)}),
    116             (_('Past 7 days'), {'%s__gte' % self.field.name: one_week_ago.strftime('%Y-%m-%d'),
    117                              '%s__lte' % f.name: today_str}),
    118             (_('This month'), {'%s__year' % self.field.name: str(today.year),
    119                              '%s__month' % f.name: str(today.month)}),
    120             (_('This year'), {'%s__year' % self.field.name: str(today.year)})
     114            (_('Today'), {'%s__year' % self.field_path: str(today.year),
     115                       '%s__month' % self.field_path: str(today.month),
     116                       '%s__day' % self.field_path: str(today.day)}),
     117            (_('Past 7 days'), {'%s__gte' % self.field_path: one_week_ago.strftime('%Y-%m-%d'),
     118                             '%s__lte' % self.field_path: today_str}),
     119            (_('This month'), {'%s__year' % self.field_path: str(today.year),
     120                             '%s__month' % self.field_path: str(today.month)}),
     121            (_('This year'), {'%s__year' % self.field_path: str(today.year)})
    121122        )
    122123
    123124    def title(self):
    class DateFieldFilterSpec(FilterSpec): 
    132133FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec)
    133134
    134135class BooleanFieldFilterSpec(FilterSpec):
    135     def __init__(self, f, request, params, model, model_admin):
    136         super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin)
    137         self.lookup_kwarg = '%s__exact' % f.name
    138         self.lookup_kwarg2 = '%s__isnull' % f.name
     136    def __init__(self, f, request, params, model, model_admin, field_path=None):
     137        super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     138        self.lookup_kwarg = '%s__exact' % self.field_path
     139        self.lookup_kwarg2 = '%s__isnull' % self.field_path
    139140        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    140141        self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None)
    141142
    FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f 
    158159# if a field is eligible to use the BooleanFieldFilterSpec, that'd be much
    159160# more appropriate, and the AllValuesFilterSpec won't get used for it.
    160161class AllValuesFilterSpec(FilterSpec):
    161     def __init__(self, f, request, params, model, model_admin):
    162         super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin)
    163         self.lookup_val = request.GET.get(f.name, None)
    164         self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
     162    def __init__(self, f, request, params, model, model_admin, field_path=None):
     163        super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)
     164        self.lookup_val = request.GET.get(self.field_path, None)
     165        #self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
     166        self.lookup_choices = model._default_manager.all().distinct().order_by(f.name).values(f.name)
    165167
    166168    def title(self):
    167169        return self.field.verbose_name
    168170
    169171    def choices(self, cl):
    170172        yield {'selected': self.lookup_val is None,
    171                'query_string': cl.get_query_string({}, [self.field.name]),
     173               'query_string': cl.get_query_string({}, [self.field_path]),
    172174               'display': _('All')}
    173175        for val in self.lookup_choices:
    174176            val = smart_unicode(val[self.field.name])
    175177            yield {'selected': self.lookup_val == val,
    176                    'query_string': cl.get_query_string({self.field.name: val}),
     178                   'query_string': cl.get_query_string({self.field_path: val}),
    177179                   'display': val}
    178180FilterSpec.register(lambda f: True, AllValuesFilterSpec)
  • django/contrib/admin/validation.py

    diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
    index ccade8a..092656c 100644
    a b def check_isdict(cls, label, obj): 
    242242
    243243def get_field(cls, model, opts, label, field):
    244244    try:
    245         return opts.get_field(field)
     245        if '__' in field:
     246            f = None
     247            m = model
     248            path = field.split('__')
     249            for field_name in path[:-1]:
     250                f = model._meta.get_field(field_name)
     251                model = f.rel.to
     252            return opts.get_field(path[0])
     253        else:
     254            return opts.get_field(field)
    246255    except models.FieldDoesNotExist:
    247256        raise ImproperlyConfigured("'%s.%s' refers to field '%s' that is missing from model '%s'."
    248257                % (cls.__name__, label, field, model.__name__))
  • django/contrib/admin/views/main.py

    diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
    index d70b6da..83b9071 100644
    a b class ChangeList(object): 
    7373    def get_filters(self, request):
    7474        filter_specs = []
    7575        if self.list_filter:
    76             filter_fields = [self.lookup_opts.get_field(field_name) for field_name in self.list_filter]
    77             for f in filter_fields:
    78                 spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin)
     76            lookup_opts = self.lookup_opts
     77            for filter_name in self.list_filter:
     78                if '__' in filter_name:
     79                    f = None
     80                    model = self.model
     81                    path = filter_name.split('__')
     82                    for field_name in path[:-1]:
     83                        f = model._meta.get_field(field_name)
     84                        model = f.rel.to
     85                        f = model._meta.get_field(path[-1])
     86                        spec = FilterSpec.create(f, request, self.params, model, self.model_admin, field_path=filter_name)
     87                else:
     88                    f = lookup_opts.get_field(filter_name)
     89                    spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin)
    7990                if spec and spec.has_output():
    8091                    filter_specs.append(spec)
    8192        return filter_specs, bool(filter_specs)
Back to Top