Ticket #11402: exists.4.diff

File exists.4.diff, 4.5 KB (added by Alex Gaynor, 15 years ago)

Fix a bug jacob spotted.

  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index a5c9986..30b12da 100644
    a b class Model(object):  
    467467            if pk_set:
    468468                # Determine whether a record with the primary key already exists.
    469469                if (force_update or (not force_insert and
    470                         manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by())):
     470                        manager.filter(pk=pk_val).exists())):
    471471                    # It does already exist, so do an UPDATE.
    472472                    if force_update or non_pks:
    473473                        values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks]
  • django/db/models/manager.py

    diff --git a/django/db/models/manager.py b/django/db/models/manager.py
    index 52612d8..73d2bf5 100644
    a b class Manager(object):  
    172172
    173173    def only(self, *args, **kwargs):
    174174        return self.get_query_set().only(*args, **kwargs)
     175   
     176    def exists(self, *args, **kwargs):
     177        return self.get_query_ste().exists(*args, **kwargs)
    175178
    176179    def _insert(self, values, **kwargs):
    177180        return insert_query(self.model, values, **kwargs)
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index 46a86fc..02288c1 100644
    a b class QuerySet(object):  
    443443        self._result_cache = None
    444444        return query.execute_sql(None)
    445445    _update.alters_data = True
     446   
     447    def exists(self):
     448        if self._result_cache is None:
     449            return self.query.has_results()
     450        return bool(self._result_cache)
    446451
    447452    ##################################################
    448453    # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index 23f99e4..1a66507 100644
    a b class BaseQuery(object):  
    383383            number = min(number, self.high_mark - self.low_mark)
    384384
    385385        return number
     386   
     387    def has_results(self):
     388        """
     389        Returns whether or not there are any items in the result set this Query
     390        represents.  Does this in a super tricking way.  Basically the
     391        equivalent of QuerySet.extra(select={'a': 1}).values('a').order_by()
     392        to maximize efficiency.
     393        """
     394        c = self.clone()
     395        c.add_extra({'a': 1}, None, None, None, None, None)
     396        c.add_fields(())
     397        c.set_extra_mask(('a',))
     398        c.set_aggregate_mask(())
     399        c.clear_ordering()
     400        results = c.execute_sql()
     401        return bool(list(results))
     402
    386403
    387404    def as_sql(self, with_limits=True, with_col_aliases=False):
    388405        """
  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index cc43612..37fce68 100644
    a b class BaseModelForm(BaseForm):  
    319319            if self.instance.pk is not None:
    320320                qs = qs.exclude(pk=self.instance.pk)
    321321
    322             # This cute trick with extra/values is the most efficient way to
    323             # tell if a particular query returns any results.
    324             if qs.extra(select={'a': 1}).values('a').order_by():
     322            if qs.exists():
    325323                if len(unique_check) == 1:
    326324                    self._errors[unique_check[0]] = ErrorList([self.unique_error_message(unique_check)])
    327325                else:
    class BaseModelForm(BaseForm):  
    354352            if self.instance.pk is not None:
    355353                qs = qs.exclude(pk=self.instance.pk)
    356354
    357             # This cute trick with extra/values is the most efficient way to
    358             # tell if a particular query returns any results.
    359             if qs.extra(select={'a': 1}).values('a').order_by():
     355            if qs.exists():
    360356                self._errors[field] = ErrorList([
    361357                    self.date_error_message(lookup_type, field, unique_for)
    362358                ])
  • docs/ref/models/querysets.txt

    diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
    index efd7c54..26c76ca 100644
    a b Aggregation <topics-db-aggregation>`.  
    11141114
    11151115.. _field-lookups:
    11161116
     1117``exists()``
     1118~~~~~~~~~~~~
     1119
     1120Returns whether or not there are any items in the ``QuerySet``.  This will
     1121perform the query in the most efficient way possible.
     1122
    11171123Field lookups
    11181124-------------
    11191125
Back to Top