Ticket #2445: evallimitchoices.diff

File evallimitchoices.diff, 4.8 KB (added by michael@…, 9 years ago)

Patch to allow evaluation of callables in limit_choices_to

  • django/db/models/manipulators.py

     
    264264                # Sanity check -- Make sure the "parent" object exists.
    265265                # For example, make sure the Place exists for the Restaurant.
    266266                # Let the ObjectDoesNotExist exception propagate up.
    267                 limit_choices_to = self.opts.one_to_one_field.rel.limit_choices_to
     267                limit_choices_to = self.opts.one_to_one_field.rel.evaluate_limit_choices_to()
    268268                lookup_kwargs = {'%s__exact' % self.opts.one_to_one_field.rel.field_name: obj_key}
    269269                self.opts.one_to_one_field.rel.to.get_model_module().complex_filter(limit_choices_to).get(**lookup_kwargs)
    270270                params = dict([(f.attname, f.get_default()) for f in self.opts.fields])
  • django/db/models/fields/__init__.py

     
    291291            return first_choice + list(self.choices)
    292292        rel_model = self.rel.to
    293293        if hasattr(self.rel, 'get_related_field'):
    294             lst = [(getattr(x, self.rel.get_related_field().attname), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
     294            lst = [(getattr(x, self.rel.get_related_field().attname), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.evaluate_limit_choices_to())]
    295295        else:
    296             lst = [(x._get_pk_val(), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
     296            lst = [(x._get_pk_val(), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.evaluate_limit_choices_to())]
    297297        return first_choice + lst
    298298
    299299    def get_choices_default(self):
  • django/db/models/fields/related.py

     
    450450        for obj in value:
    451451            manager.add(obj)
    452452
    453 class ForeignKey(RelatedField, Field):
     453class LimitedChoices(object):
     454    def evaluate_limit_choices_to(self):
     455        limiters = {}
     456        if self.limit_choices_to:
     457            for id in self.limit_choices_to:
     458                value = self.limit_choices_to[id]
     459                if callable(value):
     460                    value = value()
     461                limiters[id] = value
     462        return limiters
     463
     464class ForeignKey(RelatedField, Field, LimitedChoices):
    454465    empty_strings_allowed = False
    455466    def __init__(self, to, to_field=None, **kwargs):
    456467        try:
     
    600611        if not cls._meta.one_to_one_field:
    601612            cls._meta.one_to_one_field = self
    602613
    603 class ManyToManyField(RelatedField, Field):
     614class ManyToManyField(RelatedField, Field, LimitedChoices):
    604615    def __init__(self, to, **kwargs):
    605616        kwargs['verbose_name'] = kwargs.get('verbose_name', None)
    606617        kwargs['rel'] = ManyToManyRel(to,
     
    706717    def set_attributes_from_rel(self):
    707718        pass
    708719
    709 class ManyToOneRel(object):
     720class ManyToOneRel(LimitedChoices):
    710721    def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None,
    711722        max_num_in_admin=None, num_extra_on_change=1, edit_inline=False,
    712723        related_name=None, limit_choices_to=None, lookup_overrides=None, raw_id_admin=False):
     
    729740        "Returns the Field in the 'to' object to which this relationship is tied."
    730741        return self.to._meta.get_field(self.field_name)
    731742
    732 class OneToOneRel(ManyToOneRel):
     743class OneToOneRel(ManyToOneRel,LimitedChoices):
    733744    def __init__(self, to, field_name, num_in_admin=0, edit_inline=False,
    734745        related_name=None, limit_choices_to=None, lookup_overrides=None,
    735746        raw_id_admin=False):
     
    743754        self.raw_id_admin = raw_id_admin
    744755        self.multiple = False
    745756
    746 class ManyToManyRel(object):
     757class ManyToManyRel(LimitedChoices):
    747758    def __init__(self, to, num_in_admin=0, related_name=None,
    748759        filter_interface=None, limit_choices_to=None, raw_id_admin=False, symmetrical=True):
    749760        self.to = to
  • django/contrib/admin/views/main.py

     
    733733                qs = qs & other_qs
    734734
    735735        if self.opts.one_to_one_field:
    736             qs = qs.complex_filter(self.opts.one_to_one_field.rel.limit_choices_to)
     736            qs = qs.complex_filter(self.opts.one_to_one_field.rel.evaluate_limit_choices_to())
    737737
    738738        return qs
    739739
Back to Top