Ticket #9848: filtered_update_fix.diff
File filtered_update_fix.diff, 3.2 KB (added by , 16 years ago) |
---|
-
django/db/models/sql/subqueries.py
170 170 query.extra_select = {} 171 171 first_table = query.tables[0] 172 172 if query.alias_refcount[first_table] == 1: 173 # We can remove one table from the inner query. 173 # We can remove one table from the inner query. Because the 174 # sub-select isn't selecting anything from the table being updated, 175 # the where clause may need to filter based on a foreign key being 176 # in the sub-select rather than its own primary key. 174 177 query.unref_alias(first_table) 175 178 for i in xrange(1, len(query.tables)): 176 179 table = query.tables[i] … … 178 181 break 179 182 join_info = query.alias_map[table] 180 183 query.select = [(join_info[RHS_ALIAS], join_info[RHS_JOIN_COL])] 184 for field in query.model._meta.fields: 185 if field.column == join_info[LHS_JOIN_COL]: 186 # field is either a ForeignKey field refering to table or 187 # the primary key of query.model. 188 where_filter = '%s__in' % field.name 189 break 181 190 must_pre_select = False 182 191 else: 183 192 query.select = [] 184 193 query.add_fields([query.model._meta.pk.name]) 194 where_filter = 'pk__in' 185 195 must_pre_select = not self.connection.features.update_can_self_select 186 196 187 197 # Now we adjust the current query: reset the where clause and get rid … … 194 204 idents = [] 195 205 for rows in query.execute_sql(MULTI): 196 206 idents.extend([r[0] for r in rows]) 197 self.add_filter(( 'pk__in', idents))207 self.add_filter((where_filter, idents)) 198 208 self.related_ids = idents 199 209 else: 200 210 # The fast path. Filters and updates in one query. 201 self.add_filter(( 'pk__in', query))211 self.add_filter((where_filter, query)) 202 212 for alias in self.tables[1:]: 203 213 self.alias_refcount[alias] = 0 204 214 -
tests/regressiontests/queries/models.py
1021 1021 # optimise the inner query without losing results. 1022 1022 >>> Annotation.objects.exclude(tag__children__name="t2") 1023 1023 [<Annotation: a2>] 1024 1025 # Bug #9848 1026 # This is a little tricky to test because we have to make sure that the IDs 1027 # from different tables don't happen to match. 1028 >>> Ranking.objects.filter(author__name='a1') 1029 [<Ranking: 3: a1>] 1030 >>> Ranking.objects.filter(author__name='a1').update(rank='4') 1031 1 1032 >>> r = Ranking.objects.filter(author__name='a1')[0] 1033 >>> r.id 1034 3 1035 >>> r.author.id 1036 1 1037 >>> r.rank 1038 4 1039 >>> r.rank = 3 1040 >>> r.save() 1041 >>> Ranking.objects.all() 1042 [<Ranking: 3: a1>, <Ranking: 2: a2>, <Ranking: 1: a3>] 1024 1043 """} 1025 1044 1026 1045 # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__