Django

Code

Ticket #2445: evallimitchoices.diff

File evallimitchoices.diff, 4.8 kB (added by michael@actrix.gen.nz, 2 years ago)

Patch to allow evaluation of callables in limit_choices_to

  • django/db/models/manipulators.py

    old new  
    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

    old new  
    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

    old new  
    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

    old new  
    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