Changeset 7043
- Timestamp:
- 01/28/08 08:27:53 (6 months ago)
- Files:
-
- django/branches/queryset-refactor/django/db/models/query.py (modified) (1 diff)
- django/branches/queryset-refactor/django/db/models/sql/query.py (modified) (4 diffs)
- django/branches/queryset-refactor/docs/db-api.txt (modified) (1 diff)
- django/branches/queryset-refactor/tests/modeltests/update (added)
- django/branches/queryset-refactor/tests/modeltests/update/__init__.py (added)
- django/branches/queryset-refactor/tests/modeltests/update/models.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/queryset-refactor/django/db/models/query.py
r7030 r7043 255 255 self._result_cache = None 256 256 delete.alters_data = True 257 258 def update(self, **kwargs): 259 """ 260 Updates all elements in the current QuerySet, setting all the given 261 fields to the appropriate values. 262 """ 263 query = self.query.clone(sql.UpdateQuery) 264 query.add_update_values(kwargs) 265 query.execute_sql(None) 266 self._result_cache=None 267 update.alters_Data = True 257 268 258 269 ################################################## django/branches/queryset-refactor/django/db/models/sql/query.py
r7042 r7043 175 175 obj.extra_order_by = self.extra_order_by[:] 176 176 obj.__dict__.update(kwargs) 177 if hasattr(obj, '_setup_query'): 178 obj._setup_query() 177 179 return obj 178 180 … … 1160 1162 def __init__(self, *args, **kwargs): 1161 1163 super(UpdateQuery, self).__init__(*args, **kwargs) 1164 self._setup_query() 1165 1166 def _setup_query(self): 1167 """ 1168 Run on initialisation and after cloning. 1169 """ 1162 1170 self.values = [] 1163 1171 … … 1167 1175 parameters. 1168 1176 """ 1169 assert len(self.tables) == 1, \ 1170 "Can only update one table at a time." 1177 self.select_related = False 1178 self.pre_sql_setup() 1179 if len(tables) != 1: 1180 raise TypeError('Updates can only access a single database table at a time.') 1171 1181 result = ['UPDATE %s' % self.tables[0]] 1172 1182 result.append('SET') 1173 1183 qn = self.quote_name_unless_alias 1174 values = ['%s = %s' % (qn(v[0]), v[1]) for v in self.values] 1184 values, update_params = [], [] 1185 for name, val in self.values: 1186 if val is not None: 1187 values.append('%s = %%s' % qn(name)) 1188 update_params.append(val) 1189 else: 1190 values.append('%s = NULL' % qn(name)) 1175 1191 result.append(', '.join(values)) 1176 1192 where, params = self.where.as_sql() 1177 1193 result.append('WHERE %s' % where) 1178 return ' '.join(result), tuple(params) 1179 1180 def do_query(self, table, values, where): 1181 self.tables = [table] 1182 self.values = values 1183 self.where = where 1184 self.execute_sql(NONE) 1194 return ' '.join(result), tuple(update_params + params) 1185 1195 1186 1196 def clear_related(self, related_field, pk_list): … … 1192 1202 """ 1193 1203 for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 1194 where = self.where_class()1204 self.where = self.where_class() 1195 1205 f = self.model._meta.pk 1196 where.add((None, f.column, f, 'in',1206 self.where.add((None, f.column, f, 'in', 1197 1207 pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), 1198 1208 AND) 1199 values = [(related_field.column, 'NULL')] 1200 self.do_query(self.model._meta.db_table, values, where) 1209 self.values = [(related_field.column, None)] 1210 self.execute_sql(None) 1211 1212 def add_update_values(self, values): 1213 from django.db.models.base import Model 1214 for name, val in values.items(): 1215 field, direct, m2m = self.model._meta.get_field_by_name(name) 1216 if not direct or m2m: 1217 # Can only update non-relation fields and foreign keys. 1218 raise TypeError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field) 1219 if field.rel and isinstance(val, Model): 1220 val = val.pk 1221 self.values.append((field.column, val)) 1201 1222 1202 1223 class DateQuery(Query): django/branches/queryset-refactor/docs/db-api.txt
r7042 r7043 1973 1973 Entry.objects.all().delete() 1974 1974 1975 Updating multiple objects at once 1976 ================================= 1977 1978 **New in Django development version** 1979 1980 Sometimes you want to set a field to a particular value for all the objects in 1981 a queryset. You can do this with the ``update()`` method. For example:: 1982 1983 # Update all the headlings to the same value. 1984 Entry.objects.all().update(headline='Everything is the same') 1985 1986 You can only set non-relation fields and ``ForeignKey`` fields using this 1987 method and the value you set the field to must be a normal Python value (you 1988 can't set a field to be equal to some other field at the moment). 1989 1990 To update ``ForeignKey`` fields, set the new value to be the new model 1991 instance you want to point to. Example:: 1992 1993 b = Blog.objects.get(pk=1) 1994 # Make all entries belong to this blog. 1995 Entry.objects.all().update(blog=b) 1996 1997 The ``update()`` method is applied instantly and doesn't return anything 1998 (similar to ``delete()``). The only restriction on the queryset that is 1999 updated is that it can only access one database table, the model's main 2000 table. So don't try to filter based on related fields or anything like that; 2001 it won't work. 2002 1975 2003 Extra instance methods 1976 2004 ======================
