Django

Code

Changeset 2850

Show
Ignore:
Timestamp:
05/05/06 19:26:24 (2 years ago)
Author:
lukeplant
Message:

Fixed #1579 - added support for 'Q' objects in limit_choices_to.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/admin/views/main.py

    r2827 r2850  
    715715 
    716716        if self.opts.one_to_one_field: 
    717             qs = qs.filter(**self.opts.one_to_one_field.rel.limit_choices_to) 
     717            qs = qs.complex_filter(self.opts.one_to_one_field.rel.limit_choices_to) 
    718718 
    719719        return qs 
  • django/trunk/django/db/models/fields/__init__.py

    r2809 r2850  
    296296        rel_model = self.rel.to 
    297297        return first_choice + [(x._get_pk_val(), str(x)) 
    298                                for x in rel_model._default_manager.filter(**self.rel.limit_choices_to)] 
     298                               for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)] 
    299299 
    300300    def get_choices_default(self): 
  • django/trunk/django/db/models/fields/related.py

    r2828 r2850  
    680680        self.min_num_in_admin, self.max_num_in_admin = min_num_in_admin, max_num_in_admin 
    681681        self.num_extra_on_change, self.related_name = num_extra_on_change, related_name 
    682         self.limit_choices_to = limit_choices_to or {} 
     682        if limit_choices_to is None: 
     683            limit_choices_to = {} 
     684        self.limit_choices_to = limit_choices_to 
    683685        self.lookup_overrides = lookup_overrides or {} 
    684686        self.raw_id_admin = raw_id_admin 
     
    696698        self.num_in_admin, self.edit_inline = num_in_admin, edit_inline 
    697699        self.related_name = related_name 
    698         self.limit_choices_to = limit_choices_to or {} 
     700        if limit_choices_to is None: 
     701            limit_choices_to = {} 
     702        self.limit_choices_to = limit_choices_to 
    699703        self.lookup_overrides = lookup_overrides or {} 
    700704        self.raw_id_admin = raw_id_admin 
     
    708712        self.related_name = related_name 
    709713        self.filter_interface = filter_interface 
    710         self.limit_choices_to = limit_choices_to or {} 
     714        if limit_choices_to is None: 
     715            limit_choices_to = {}         
     716        self.limit_choices_to = limit_choices_to 
    711717        self.edit_inline = False 
    712718        self.raw_id_admin = raw_id_admin 
  • django/trunk/django/db/models/manager.py

    r2809 r2850  
    6969        return self.get_query_set().filter(*args, **kwargs) 
    7070 
     71    def complex_filter(self, *args, **kwargs): 
     72        return self.get_query_set().complex_filter(*args, **kwargs) 
     73 
    7174    def exclude(self, *args, **kwargs): 
    7275        return self.get_query_set().exclude(*args, **kwargs) 
  • django/trunk/django/db/models/manipulators.py

    r2809 r2850  
    262262                # For example, make sure the Place exists for the Restaurant. 
    263263                # Let the ObjectDoesNotExist exception propagate up. 
    264                 lookup_kwargs = self.opts.one_to_one_field.rel.limit_choices_to 
    265                 lookup_kwargs['%s__exact' % self.opts.one_to_one_field.rel.field_name] = obj_key 
    266                 self.opts.one_to_one_field.rel.to.get_model_module().get(**lookup_kwargs) 
     264                limit_choices_to = self.opts.one_to_one_field.rel.limit_choices_to 
     265                lookup_kwargs = {'%s__exact' % self.opts.one_to_one_field.rel.field_name: obj_key} 
     266                self.opts.one_to_one_field.rel.to.get_model_module().complex_filter(limit_choices_to).get(**lookup_kwargs) 
    267267                params = dict([(f.attname, f.get_default()) for f in self.opts.fields]) 
    268268                params[self.opts.pk.attname] = obj_key 
  • django/trunk/django/db/models/query.py

    r2809 r2850  
    297297            clone._filters = clone._filters & reduce(operator.and_, args) 
    298298        return clone 
     299 
     300    def complex_filter(self, filter_obj): 
     301        """Returns a new QuerySet instance with filter_obj added to the filters. 
     302        filter_obj can be a Q object (has 'get_sql' method) or a dictionary of  
     303        keyword lookup arguments.""" 
     304        # This exists to support framework features such as 'limit_choices_to', 
     305        # and usually it will be more natural to use other methods. 
     306        if hasattr(filter_obj, 'get_sql'): 
     307            return self._filter_or_exclude(None, filter_obj) 
     308        else: 
     309            return self._filter_or_exclude(Q, **filter_obj) 
    299310 
    300311    def select_related(self, true_or_false=True): 
  • django/trunk/docs/model-api.txt

    r2849 r2850  
    704704                             ``pub_date`` before the current date/time to be 
    705705                             chosen. 
     706 
     707                             Instead of a dictionary this can also be a ``Q`` object 
     708                             (an object with a ``get_sql()`` method) for more complex 
     709                             queries. 
    706710 
    707711                             Not compatible with ``edit_inline``. 
  • django/trunk/tests/modeltests/or_lookups/models.py

    r2809 r2850  
    8787{1: Hello} 
    8888 
     89# The 'complex_filter' method supports framework features such as  
     90# 'limit_choices_to' which normally take a single dictionary of lookup arguments 
     91# but need to support arbitrary queries via Q objects too. 
     92>>> Article.objects.complex_filter({'pk': 1}) 
     93[Hello] 
     94>>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2)) 
     95[Hello, Goodbye] 
    8996"""