mirror of
https://github.com/django/django.git
synced 2025-07-06 02:39:12 +00:00
queryset-refactor: Added support for munging of insert columns.
Needed to support cases like GIS fields. Patch from Justin Bronn. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7318 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d20996b58d
commit
9ee77a7501
@ -126,9 +126,9 @@ class UpdateQuery(Query):
|
|||||||
result = ['UPDATE %s' % qn(table)]
|
result = ['UPDATE %s' % qn(table)]
|
||||||
result.append('SET')
|
result.append('SET')
|
||||||
values, update_params = [], []
|
values, update_params = [], []
|
||||||
for name, val in self.values:
|
for name, val, placeholder in self.values:
|
||||||
if val is not None:
|
if val is not None:
|
||||||
values.append('%s = %%s' % qn(name))
|
values.append('%s = %s' % (qn(name), placeholder))
|
||||||
update_params.append(val)
|
update_params.append(val)
|
||||||
else:
|
else:
|
||||||
values.append('%s = NULL' % qn(name))
|
values.append('%s = NULL' % qn(name))
|
||||||
@ -190,33 +190,40 @@ class UpdateQuery(Query):
|
|||||||
self.where.add((None, f.column, f, 'in',
|
self.where.add((None, f.column, f, 'in',
|
||||||
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
||||||
AND)
|
AND)
|
||||||
self.values = [(related_field.column, None)]
|
self.values = [(related_field.column, None, '%s')]
|
||||||
self.execute_sql(None)
|
self.execute_sql(None)
|
||||||
|
|
||||||
def add_update_values(self, values):
|
def add_update_values(self, values):
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
for name, val in values.items():
|
for name, val in values.iteritems():
|
||||||
field, model, direct, m2m = self.model._meta.get_field_by_name(name)
|
field, model, direct, m2m = self.model._meta.get_field_by_name(name)
|
||||||
if not direct or m2m:
|
if not direct or m2m:
|
||||||
raise FieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
|
raise FieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
|
||||||
# FIXME: Some sort of db_prep_* is probably more appropriate here.
|
# FIXME: Some sort of db_prep_* is probably more appropriate here.
|
||||||
if field.rel and isinstance(val, Model):
|
if field.rel and isinstance(val, Model):
|
||||||
val = val.pk
|
val = val.pk
|
||||||
if model:
|
|
||||||
self.add_related_update(model, field.column, val)
|
|
||||||
else:
|
|
||||||
self.values.append((field.column, val))
|
|
||||||
|
|
||||||
def add_related_update(self, model, column, value):
|
# Getting the placeholder for the field.
|
||||||
|
if hasattr(field, 'get_placeholder'):
|
||||||
|
placeholder = field.get_placeholder(val)
|
||||||
|
else:
|
||||||
|
placeholder = '%s'
|
||||||
|
|
||||||
|
if model:
|
||||||
|
self.add_related_update(model, field.column, val, placeholder)
|
||||||
|
else:
|
||||||
|
self.values.append((field.column, val, placeholder))
|
||||||
|
|
||||||
|
def add_related_update(self, model, column, value, placeholder):
|
||||||
"""
|
"""
|
||||||
Adds (name, value) to an update query for an ancestor model.
|
Adds (name, value) to an update query for an ancestor model.
|
||||||
|
|
||||||
Updates are coalesced so that we only run one update query per ancestor.
|
Updates are coalesced so that we only run one update query per ancestor.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.related_updates[model].append((column, value))
|
self.related_updates[model].append((column, value, placeholder))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.related_updates[model] = [(column, value)]
|
self.related_updates[model] = [(column, value, placeholder)]
|
||||||
|
|
||||||
def get_related_updates(self):
|
def get_related_updates(self):
|
||||||
"""
|
"""
|
||||||
@ -227,7 +234,7 @@ class UpdateQuery(Query):
|
|||||||
if not self.related_updates:
|
if not self.related_updates:
|
||||||
return []
|
return []
|
||||||
result = []
|
result = []
|
||||||
for model, values in self.related_updates.items():
|
for model, values in self.related_updates.iteritems():
|
||||||
query = UpdateQuery(model, self.connection)
|
query = UpdateQuery(model, self.connection)
|
||||||
query.values = values
|
query.values = values
|
||||||
if self.related_ids:
|
if self.related_ids:
|
||||||
@ -272,20 +279,31 @@ class InsertQuery(Query):
|
|||||||
parameters. This provides a way to insert NULL and DEFAULT keywords
|
parameters. This provides a way to insert NULL and DEFAULT keywords
|
||||||
into the query, for example.
|
into the query, for example.
|
||||||
"""
|
"""
|
||||||
func = lambda x: self.model._meta.get_field_by_name(x)[0].column
|
func = lambda x: self.model._meta.get_field_by_name(x)[0]
|
||||||
# keys() and values() return items in the same order, providing the
|
# keys() and values() return items in the same order, providing the
|
||||||
# dictionary hasn't changed between calls. So the dual iteration here
|
# dictionary hasn't changed between calls. So the dual iteration here
|
||||||
# works as intended.
|
# works as intended.
|
||||||
for name in insert_values:
|
placeholders, values = [], []
|
||||||
|
for name, val in insert_values.iteritems():
|
||||||
if name == 'pk':
|
if name == 'pk':
|
||||||
name = self.model._meta.pk.name
|
name = self.model._meta.pk.name
|
||||||
self.columns.append(func(name))
|
# Getting the Field associated w/the name.
|
||||||
if raw_values:
|
field = func(name)
|
||||||
self.values.extend(insert_values.values())
|
|
||||||
|
if hasattr(field, 'get_placeholder'):
|
||||||
|
# Some fields (e.g. geo fields) need special munging before
|
||||||
|
# they can be inserted.
|
||||||
|
placeholders.append(field.get_placeholder(val))
|
||||||
|
else:
|
||||||
|
placeholders.append('%s')
|
||||||
|
|
||||||
|
self.columns.append(field.column)
|
||||||
|
values.append(val)
|
||||||
|
if raw_values:
|
||||||
|
self.values.extend(values)
|
||||||
else:
|
else:
|
||||||
values = insert_values.values()
|
|
||||||
self.params += tuple(values)
|
self.params += tuple(values)
|
||||||
self.values.extend(['%s'] * len(values))
|
self.values.extend(placeholders)
|
||||||
|
|
||||||
class DateQuery(Query):
|
class DateQuery(Query):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user