Changeset 7498
- Timestamp:
- 04/28/08 09:08:46 (2 months ago)
- Files:
-
- django/branches/gis (modified) (1 prop)
- django/branches/gis/django/contrib/admin/views/main.py (modified) (1 diff)
- django/branches/gis/django/db/backends/__init__.py (modified) (1 diff)
- django/branches/gis/django/db/backends/mysql/base.py (modified) (1 diff)
- django/branches/gis/django/db/backends/mysql_old/base.py (modified) (1 diff)
- django/branches/gis/django/db/models/fields/__init__.py (modified) (2 diffs)
- django/branches/gis/django/db/models/query.py (modified) (2 diffs)
- django/branches/gis/django/db/models/sql/constants.py (modified) (1 diff)
- django/branches/gis/django/db/models/sql/query.py (modified) (3 diffs)
- django/branches/gis/django/db/models/sql/subqueries.py (modified) (4 diffs)
- django/branches/gis/docs/db-api.txt (modified) (6 diffs)
- django/branches/gis/tests/modeltests/many_to_one/models.py (modified) (3 diffs)
- django/branches/gis/tests/regressiontests/queries/models.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis
- Property svnmerge-integrated changed from /django/trunk:1-7481 to /django/trunk:1-7497
django/branches/gis/django/contrib/admin/views/main.py
r7482 r7498 717 717 break 718 718 719 # Calculate lookup_order_field.720 # If the order-by field is a field with a relationship, order by the721 # value in the related table.722 lookup_order_field = self.order_field723 try:724 f = self.lookup_opts.get_field(self.order_field, many_to_many=False)725 except models.FieldDoesNotExist:726 pass727 else:728 if isinstance(f.rel, models.OneToOneRel):729 # For OneToOneFields, don't try to order by the related object's ordering criteria.730 pass731 elif isinstance(f.rel, models.ManyToOneRel):732 rel_ordering = f.rel.to._meta.ordering and f.rel.to._meta.ordering[0] or f.rel.to._meta.pk.column733 lookup_order_field = '%s.%s' % (f.rel.to._meta.db_table, rel_ordering)734 735 719 # Set ordering. 736 qs = qs.order_by((self.order_type == 'desc' and '-' or '') + lookup_order_field) 720 if self.order_field: 721 qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field)) 737 722 738 723 # Apply keyword searches. django/branches/gis/django/db/backends/__init__.py
r7482 r7498 52 52 uses_custom_query_class = False 53 53 empty_fetchmany_value = [] 54 update_can_self_select = True 54 55 55 56 class BaseDatabaseOperations(object): django/branches/gis/django/db/backends/mysql/base.py
r7482 r7498 64 64 inline_fk_references = False 65 65 empty_fetchmany_value = () 66 update_can_self_select = False 66 67 67 68 class DatabaseOperations(BaseDatabaseOperations): django/branches/gis/django/db/backends/mysql_old/base.py
r7482 r7498 68 68 inline_fk_references = False 69 69 empty_fetchmany_value = () 70 update_can_self_select = False 70 71 71 72 class DatabaseOperations(BaseDatabaseOperations): django/branches/gis/django/db/models/fields/__init__.py
r7482 r7498 10 10 from django.db import get_creation_module 11 11 from django.db.models import signals 12 from django.db.models.query_utils import QueryWrapper 12 13 from django.dispatch import dispatcher 13 14 from django.conf import settings … … 227 228 def get_db_prep_lookup(self, lookup_type, value): 228 229 "Returns field's value prepared for database lookup." 230 if hasattr(value, 'as_sql'): 231 sql, params = value.as_sql() 232 return QueryWrapper(('(%s)' % sql), params) 229 233 if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'): 230 234 return [value] django/branches/gis/django/db/models/query.py
r7482 r7498 285 285 query.add_update_values(kwargs) 286 286 query.execute_sql(None) 287 transaction.commit_unless_managed() 287 288 self._result_cache = None 288 289 update.alters_data = True … … 496 497 # QuerySet.clone() will also set up the _fields attribute with the 497 498 # names of the model fields to select. 498 499 def __iter__(self):500 return self.iterator()501 499 502 500 def iterator(self): django/branches/gis/django/db/models/sql/constants.py
r7482 r7498 29 29 SINGLE = 'single' 30 30 31 ORDER_PATTERN = re.compile(r'\?|[-+]? \w+$')31 ORDER_PATTERN = re.compile(r'\?|[-+]?[.\w]+$') 32 32 ORDER_DIR = { 33 33 'ASC': ('ASC', 'DESC'), django/branches/gis/django/db/models/sql/query.py
r7482 r7498 896 896 (filter_string, value). E.g. ('name__contains', 'fred') 897 897 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). 898 If 'negate' is True, this is an exclude() filter. It's important to 899 note that this method does not negate anything in the where-clause 900 object when inserting the filter constraints. This is because negated 901 filters often require multiple calls to add_filter() and the negation 902 should only happen once. So the caller is responsible for this (the 903 caller will normally be add_q(), so that as an example). 904 905 If 'trim' is True, we automatically trim the final join group (used 906 internally when constructing nested queries). 901 907 902 908 If 'can_reuse' is a set, we are processing a component of a … … 1002 1008 self.where.add((alias, col, field, lookup_type, value), connector) 1003 1009 if negate: 1004 self.where.negate()1005 1010 for alias in join_list: 1006 1011 self.promote_alias(alias) … … 1040 1045 self.add_q(child, used_aliases) 1041 1046 self.where.end_subtree() 1042 if q_object.negated:1043 self.where.children[-1].negate()1044 1047 else: 1045 1048 self.add_filter(child, connector, q_object.negated, 1046 1049 can_reuse=used_aliases) 1047 1050 connector = q_object.connector 1051 if q_object.negated: 1052 self.where.negate() 1048 1053 if subtree: 1049 1054 self.where.end_subtree() django/branches/gis/django/db/models/sql/subqueries.py
r7482 r7498 96 96 def _setup_query(self): 97 97 """ 98 Runs on initiali sation and after cloning. Any attributes that would98 Runs on initialization and after cloning. Any attributes that would 99 99 normally be set in __init__ should go in here, instead, so that they 100 100 are also set up after a clone() call. … … 160 160 query = self.clone(klass=Query) 161 161 query.bump_prefix() 162 query.select = []163 162 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 165 178 166 179 # Now we adjust the current query: reset the where clause and get rid 167 180 # of all the tables we don't need (since they're in the sub-select). 168 181 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). 170 186 idents = [] 171 187 for rows in query.execute_sql(MULTI): … … 174 190 self.related_ids = idents 175 191 else: 192 # The fast path. Filters and updates in one query. 176 193 self.add_filter(('pk__in', query)) 177 194 for alias in self.tables[1:]: … … 350 367 self.select = [select] 351 368 self.select_fields = [None] 369 self.select_related = False # See #7097. 352 370 self.distinct = True 353 371 self.order_by = order == 'ASC' and [1] or [-1] django/branches/gis/docs/db-api.txt
r7482 r7498 528 528 529 529 **New in Django development version:** The syntax for ordering across related 530 models has changed. See the `Django 0.96 documentation`_ for the old behavio ur.530 models has changed. See the `Django 0.96 documentation`_ for the old behavior. 531 531 532 532 .. _Django 0.96 documentation: http://www.djangoproject.com/documentation/0.96/model-api/#floatfield … … 541 541 **New in Django development version** 542 542 543 If you want to reverse the order in which a queryset's elements are returned, 544 you can use the ``reverse()`` method. Calling ``reverse()`` a second time545 restores theordering back to the normal direction.543 Use the ``reverse()`` method to reverse the order in which a queryset's 544 elements are returned. Calling ``reverse()`` a second time restores the 545 ordering back to the normal direction. 546 546 547 547 To retrieve the ''last'' five items in a queryset, you could do this:: … … 553 553 penultimate item and so on. If we had a Python sequence and looked at 554 554 ``seq[:-5]``, we would see the fifth-last item first. Django doesn't support 555 that mode of access (slicing from the end), since it is not possible to do it555 that mode of access (slicing from the end), because it's not possible to do it 556 556 efficiently in SQL. 557 557 … … 1661 1661 filter statement, not the ``Entry`` items. 1662 1662 1663 All of this behavio ur also applies to ``exclude()``: all the conditions in a1663 All of this behavior also applies to ``exclude()``: all the conditions in a 1664 1664 single ``exclude()`` statement apply to a single instance (if those conditions 1665 1665 are talking about the same multi-valued relation). Conditions in subsequent … … 2102 2102 2103 2103 Sometimes you want to set a field to a particular value for all the objects in 2104 a queryset. You can do this with the ``update()`` method. For example::2105 2106 # Update all the headlines to the same value.2107 Entry.objects. all().update(headline='Everything is the same')2104 a ``QuerySet``. You can do this with the ``update()`` method. For example:: 2105 2106 # Update all the headlines with pub_date in 2007. 2107 Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same') 2108 2108 2109 2109 You can only set non-relation fields and ``ForeignKey`` fields using this 2110 method and the value you set the field to must be a normal Python value (you2111 can't set a field to be equal to some other field at the moment).2110 method, and the value you set the field to must be a hard-coded Python value 2111 (i.e., you can't set a field to be equal to some other field at the moment). 2112 2112 2113 2113 To update ``ForeignKey`` fields, set the new value to be the new model … … 2115 2115 2116 2116 b = Blog.objects.get(pk=1) 2117 # Make all entries belong to this blog.2117 # Change every Entry so that it belongs to this Blog. 2118 2118 Entry.objects.all().update(blog=b) 2119 2119 2120 2120 The ``update()`` method is applied instantly and doesn't return anything 2121 (similar to ``delete()``). The only restriction on the querysetthat is2121 (similar to ``delete()``). The only restriction on the ``QuerySet`` that is 2122 2122 updated is that it can only access one database table, the model's main 2123 2123 table. So don't try to filter based on related fields or anything like that; django/branches/gis/tests/modeltests/many_to_one/models.py
r7482 r7498 247 247 [<Reporter: John Smith>] 248 248 249 # Check that implied __exact also works 249 # Check that implied __exact also works. 250 250 >>> Reporter.objects.filter(article__reporter=r).distinct() 251 251 [<Reporter: John Smith>] … … 267 267 [<Reporter: John Smith>] 268 268 269 # Deletes using a join in the query269 # You can delete using a JOIN in the query. 270 270 >>> Reporter.objects.filter(article__headline__startswith='This').delete() 271 271 >>> Reporter.objects.all() … … 274 274 [] 275 275 276 # Check that Article.objects.select_related().dates() works properly when 277 # there are multiple Articles with the same date but different foreign-key 278 # objects (Reporters). 279 >>> r1 = Reporter.objects.create(first_name='Mike', last_name='Royko', email='royko@suntimes.com') 280 >>> r2 = Reporter.objects.create(first_name='John', last_name='Kass', email='jkass@tribune.com') 281 >>> a1 = Article.objects.create(headline='First', pub_date=datetime(1980, 4, 23), reporter=r1) 282 >>> a2 = Article.objects.create(headline='Second', pub_date=datetime(1980, 4, 23), reporter=r2) 283 >>> Article.objects.select_related().dates('pub_date', 'day') 284 [datetime.datetime(1980, 4, 23, 0, 0)] 285 >>> Article.objects.select_related().dates('pub_date', 'month') 286 [datetime.datetime(1980, 4, 1, 0, 0)] 287 >>> Article.objects.select_related().dates('pub_date', 'year') 288 [datetime.datetime(1980, 1, 1, 0, 0)] 276 289 """} django/branches/gis/tests/regressiontests/queries/models.py
r7482 r7498 117 117 class Meta: 118 118 ordering = ['z'] 119 120 # A model and custom default manager combination. 121 class 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 126 class 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 119 137 120 138 __test__ = {'API_TESTS':""" … … 655 673 >>> s = qs.query.as_sql() # test passes if this doesn't raise an exception. 656 674 675 Bug #7098 -- Make sure semi-deprecated ordering by related models syntax still 676 works. 677 >>> Item.objects.values('note__note').order_by('queries_note.note', 'id') 678 [{'note__note': u'n2'}, {'note__note': u'n3'}, {'note__note': u'n3'}, {'note__note': u'n3'}] 679 680 Bug #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 690 More 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 698 Bug #7095 699 Updates that are filtered on the model being updated are somewhat tricky to get 700 in MySQL. This exercises that case. 701 >>> mm = ManagedModel.objects.create(data='mm1', tag=t1, public=True) 702 >>> ManagedModel.objects.update(data='mm') 703 657 704 """} 658 705
