Django

Code

Changeset 7500

Show
Ignore:
Timestamp:
04/28/08 09:43:46 (2 months ago)
Author:
brosner
Message:

newforms-admin: Merged from trunk up to [7499].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/newforms-admin

    • Property svnmerge-integrated changed from /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7491 to /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7499
  • django/branches/newforms-admin/django/db/backends/__init__.py

    r7479 r7500  
    5252    uses_custom_query_class = False 
    5353    empty_fetchmany_value = [] 
     54    update_can_self_select = True 
    5455 
    5556class BaseDatabaseOperations(object): 
  • django/branches/newforms-admin/django/db/backends/mysql/base.py

    r7479 r7500  
    6464    inline_fk_references = False 
    6565    empty_fetchmany_value = () 
     66    update_can_self_select = False 
    6667 
    6768class DatabaseOperations(BaseDatabaseOperations): 
  • django/branches/newforms-admin/django/db/backends/mysql_old/base.py

    r7479 r7500  
    6868    inline_fk_references = False 
    6969    empty_fetchmany_value = () 
     70    update_can_self_select = False 
    7071 
    7172class DatabaseOperations(BaseDatabaseOperations): 
  • django/branches/newforms-admin/django/db/models/fields/__init__.py

    r7479 r7500  
    1010from django.db import get_creation_module 
    1111from django.db.models import signals 
     12from django.db.models.query_utils import QueryWrapper 
    1213from django.dispatch import dispatcher 
    1314from django.conf import settings 
     
    225226    def get_db_prep_lookup(self, lookup_type, value): 
    226227        "Returns field's value prepared for database lookup." 
     228        if hasattr(value, 'as_sql'): 
     229            sql, params = value.as_sql() 
     230            return QueryWrapper(('(%s)' % sql), params) 
    227231        if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'): 
    228232            return [value] 
  • django/branches/newforms-admin/django/db/models/query.py

    r7492 r7500  
    2929    ######################## 
    3030 
     31    def __getstate__(self): 
     32        """ 
     33        Allows the Queryset to be pickled. 
     34        """ 
     35        # Force the cache to be fully populated. 
     36        len(self) 
     37 
     38        obj_dict = self.__dict__.copy() 
     39        obj_dict['_iter'] = None 
     40        return obj_dict 
     41 
    3142    def __repr__(self): 
    3243        return repr(list(self)) 
     
    3849        if self._result_cache is None: 
    3950            if self._iter: 
    40                 self._result_cache = list(self._iter()
     51                self._result_cache = list(self._iter
    4152            else: 
    4253                self._result_cache = list(self.iterator()) 
     
    498509        # names of the model fields to select. 
    499510 
    500     def __iter__(self): 
    501         return self.iterator() 
    502  
    503511    def iterator(self): 
    504512        self.query.trim_extra_select(self.extra_names) 
  • django/branches/newforms-admin/django/db/models/sql/query.py

    r7479 r7500  
    9999        memo[id(self)] = result 
    100100        return result 
     101 
     102    def __getstate__(self): 
     103        """ 
     104        Pickling support. 
     105        """ 
     106        obj_dict = self.__dict__.copy() 
     107        del obj_dict['connection'] 
     108        return obj_dict 
     109 
     110    def __setstate__(self, obj_dict): 
     111        """ 
     112        Unpickling support. 
     113        """ 
     114        self.__dict__.update(obj_dict) 
     115        # XXX: Need a better solution for this when multi-db stuff is 
     116        # supported. It's the only class-reference to the module-level 
     117        # connection variable. 
     118        self.connection = connection 
    101119 
    102120    def get_meta(self): 
     
    896914        (filter_string, value). E.g. ('name__contains', 'fred') 
    897915 
    898         If 'negate' is True, this is an exclude() filter. If 'trim' is True, we 
    899         automatically trim the final join group (used internally when 
    900         constructing nested queries). 
     916        If 'negate' is True, this is an exclude() filter. It's important to 
     917        note that this method does not negate anything in the where-clause 
     918        object when inserting the filter constraints. This is because negated 
     919        filters often require multiple calls to add_filter() and the negation 
     920        should only happen once. So the caller is responsible for this (the 
     921        caller will normally be add_q(), so that as an example). 
     922 
     923        If 'trim' is True, we automatically trim the final join group (used 
     924        internally when constructing nested queries). 
    901925 
    902926        If 'can_reuse' is a set, we are processing a component of a 
     
    10021026        self.where.add((alias, col, field, lookup_type, value), connector) 
    10031027        if negate: 
    1004             self.where.negate() 
    10051028            for alias in join_list: 
    10061029                self.promote_alias(alias) 
     
    10401063                self.add_q(child, used_aliases) 
    10411064                self.where.end_subtree() 
    1042                 if q_object.negated: 
    1043                     self.where.children[-1].negate() 
    10441065            else: 
    10451066                self.add_filter(child, connector, q_object.negated, 
    10461067                        can_reuse=used_aliases) 
    10471068            connector = q_object.connector 
     1069        if q_object.negated: 
     1070            self.where.negate() 
    10481071        if subtree: 
    10491072            self.where.end_subtree() 
  • django/branches/newforms-admin/django/db/models/sql/subqueries.py

    r7492 r7500  
    160160        query = self.clone(klass=Query) 
    161161        query.bump_prefix() 
    162         query.select = [] 
    163162        query.extra_select = {} 
    164         query.add_fields([query.model._meta.pk.name]) 
     163        first_table = query.tables[0] 
     164        if query.alias_refcount[first_table] == 1: 
     165            # We can remove one table from the inner query. 
     166            query.unref_alias(first_table) 
     167            for i in xrange(1, len(query.tables)): 
     168                table = query.tables[i] 
     169                if query.alias_refcount[table]: 
     170                    break 
     171            join_info = query.alias_map[table] 
     172            query.select = [(join_info[RHS_ALIAS], join_info[RHS_JOIN_COL])] 
     173            must_pre_select = False 
     174        else: 
     175            query.select = [] 
     176            query.add_fields([query.model._meta.pk.name]) 
     177            must_pre_select = not self.connection.features.update_can_self_select 
    165178 
    166179        # Now we adjust the current query: reset the where clause and get rid 
    167180        # of all the tables we don't need (since they're in the sub-select). 
    168181        self.where = self.where_class() 
    169         if self.related_updates: 
     182        if self.related_updates or must_pre_select: 
     183            # Either we're using the idents in multiple update queries (so 
     184            # don't want them to change), or the db backend doesn't support 
     185            # selecting from the updating table (e.g. MySQL). 
    170186            idents = [] 
    171187            for rows in query.execute_sql(MULTI): 
     
    174190            self.related_ids = idents 
    175191        else: 
     192            # The fast path. Filters and updates in one query. 
    176193            self.add_filter(('pk__in', query)) 
    177194        for alias in self.tables[1:]: 
  • django/branches/newforms-admin/docs/db-api.txt

    r7492 r7500  
    376376      iterating over a ``QuerySet`` will take advantage of your database to 
    377377      load data and instantiate objects only as you need them. 
     378 
     379 
     380Pickling QuerySets 
     381~~~~~~~~~~~~~~~~~~ 
     382 
     383If you pickle_ a ``QuerySet``, this will also force all the results to be 
     384loaded into memory prior to pickling. This is because pickling is usually used 
     385as a precursor to caching and when the cached queryset is reloaded, you want 
     386the results to already be present. This means that when you unpickle a 
     387``QuerySet``, it contains the results at the moment it was pickled, rather 
     388than the results that are currently in the database. 
     389 
     390If you only want to pickle the necessary information to recreate the 
     391``Queryset`` from the database at a later time, pickle the ``query`` attribute 
     392of the ``QuerySet``. You can then recreate the original ``QuerySet`` (without 
     393any results loaded) using some code like this:: 
     394 
     395    >>> import pickle 
     396    >>> query = pickle.loads(s)     # Assuming 's' is the pickled string. 
     397    >>> qs = MyModel.objects.all() 
     398    >>> qs.query = query            # Restore the original 'query'. 
     399 
     400.. _pickle: http://docs.python.org/lib/module-pickle.html 
    378401 
    379402Limiting QuerySets 
  • django/branches/newforms-admin/tests/regressiontests/queries/models.py

    r7492 r7500  
    117117    class Meta: 
    118118        ordering = ['z'] 
     119 
     120# A model and custom default manager combination. 
     121class CustomManager(models.Manager): 
     122    def get_query_set(self): 
     123        return super(CustomManager, self).get_query_set().filter(public=True, 
     124                tag__name='t1') 
     125 
     126class ManagedModel(models.Model): 
     127    data = models.CharField(max_length=10) 
     128    tag = models.ForeignKey(Tag) 
     129    public = models.BooleanField(default=True) 
     130 
     131    objects = CustomManager() 
     132    normal_manager = models.Manager() 
     133 
     134    def __unicode__(self): 
     135        return self.data 
     136 
    119137 
    120138__test__ = {'API_TESTS':""" 
     
    659677>>> Item.objects.values('note__note').order_by('queries_note.note', 'id') 
    660678[{'note__note': u'n2'}, {'note__note': u'n3'}, {'note__note': u'n3'}, {'note__note': u'n3'}] 
     679 
     680Bug #7096 -- Make sure exclude() with multiple conditions continues to work. 
     681>>> Tag.objects.filter(parent=t1, name='t3').order_by('name') 
     682[<Tag: t3>] 
     683>>> Tag.objects.exclude(parent=t1, name='t3').order_by('name') 
     684[<Tag: t1>, <Tag: t2>, <Tag: t4>, <Tag: t5>] 
     685>>> Item.objects.exclude(tags__name='t1', name='one').order_by('name').distinct() 
     686[<Item: four>, <Item: three>, <Item: two>] 
     687>>> Item.objects.filter(name__in=['three', 'four']).exclude(tags__name='t1').order_by('name') 
     688[<Item: four>, <Item: three>] 
     689 
     690More twisted cases, involving nested negations. 
     691>>> Item.objects.exclude(~Q(tags__name='t1', name='one')) 
     692[<Item: one>] 
     693>>> Item.objects.filter(~Q(tags__name='t1', name='one'), name='two') 
     694[<Item: two>] 
     695>>> Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two') 
     696[<Item: four>, <Item: one>, <Item: three>] 
     697 
     698Bug #7095 
     699Updates that are filtered on the model being updated are somewhat tricky to get 
     700in MySQL. This exercises that case. 
     701>>> mm = ManagedModel.objects.create(data='mm1', tag=t1, public=True) 
     702>>> ManagedModel.objects.update(data='mm') 
     703 
    661704"""} 
    662705