1
0
mirror of https://github.com/django/django.git synced 2025-10-24 14:16:09 +00:00

Merged the queryset-refactor branch into trunk.

This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.

Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658


git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick
2008-04-27 02:50:16 +00:00
parent c91a30f00f
commit 9c52d56f6f
57 changed files with 5717 additions and 1739 deletions

View File

@@ -27,3 +27,8 @@ class MiddlewareNotUsed(Exception):
class ImproperlyConfigured(Exception):
"Django is somehow improperly configured"
pass
class FieldError(Exception):
"""Some kind of problem with a model field."""
pass

View File

@@ -26,7 +26,7 @@ def django_table_list(only_existing=False):
for app in models.get_apps():
for model in models.get_models(app):
tables.append(model._meta.db_table)
tables.extend([f.m2m_db_table() for f in model._meta.many_to_many])
tables.extend([f.m2m_db_table() for f in model._meta.local_many_to_many])
if only_existing:
existing = table_list()
tables = [t for t in tables if t in existing]
@@ -54,12 +54,12 @@ def sequence_list():
for app in apps:
for model in models.get_models(app):
for f in model._meta.fields:
for f in model._meta.local_fields:
if isinstance(f, models.AutoField):
sequence_list.append({'table': model._meta.db_table, 'column': f.column})
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
for f in model._meta.local_many_to_many:
sequence_list.append({'table': f.m2m_db_table(), 'column': None})
return sequence_list
@@ -149,7 +149,7 @@ def sql_delete(app, style):
if cursor and table_name_converter(model._meta.db_table) in table_names:
# The table exists, so it needs to be dropped
opts = model._meta
for f in opts.fields:
for f in opts.local_fields:
if f.rel and f.rel.to not in to_delete:
references_to_delete.setdefault(f.rel.to, []).append( (model, f) )
@@ -181,7 +181,7 @@ def sql_delete(app, style):
# Output DROP TABLE statements for many-to-many tables.
for model in app_models:
opts = model._meta
for f in opts.many_to_many:
for f in opts.local_many_to_many:
if isinstance(f.rel, generic.GenericRel):
continue
if cursor and table_name_converter(f.m2m_db_table()) in table_names:
@@ -258,7 +258,7 @@ def sql_model_create(model, style, known_models=set()):
pending_references = {}
qn = connection.ops.quote_name
inline_references = connection.features.inline_fk_references
for f in opts.fields:
for f in opts.local_fields:
col_type = f.db_type()
tablespace = f.db_tablespace or opts.db_tablespace
if col_type is None:
@@ -294,14 +294,8 @@ def sql_model_create(model, style, known_models=set()):
style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \
style.SQL_KEYWORD('NULL'))
for field_constraints in opts.unique_together:
constraint_output = [style.SQL_KEYWORD('UNIQUE')]
constraint_output.append('(%s)' % \
table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints]))
if opts.db_tablespace and connection.features.supports_tablespaces \
and connection.features.autoindexes_primary_keys:
constraint_output.append(connection.ops.tablespace_sql(
opts.db_tablespace, inline=True))
table_output.append(' '.join(constraint_output))
full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(qn(opts.db_table)) + ' (']
for i, line in enumerate(table_output): # Combine and add commas.
@@ -359,7 +353,7 @@ def many_to_many_sql_for_model(model, style):
final_output = []
qn = connection.ops.quote_name
inline_references = connection.features.inline_fk_references
for f in opts.many_to_many:
for f in opts.local_many_to_many:
if not isinstance(f.rel, generic.GenericRel):
tablespace = f.db_tablespace or opts.db_tablespace
if tablespace and connection.features.supports_tablespaces and connection.features.autoindexes_primary_keys:
@@ -466,7 +460,7 @@ def sql_indexes_for_model(model, style):
output = []
qn = connection.ops.quote_name
for f in model._meta.fields:
for f in model._meta.local_fields:
if f.db_index and not ((f.primary_key or f.unique) and connection.features.autoindexes_primary_keys):
unique = f.unique and 'UNIQUE ' or ''
tablespace = f.db_tablespace or model._meta.db_tablespace

View File

@@ -32,7 +32,7 @@ def get_validation_errors(outfile, app=None):
opts = cls._meta
# Do field-specific validation.
for f in opts.fields:
for f in opts.local_fields:
if f.name == 'id' and not f.primary_key and opts.pk.name == 'id':
e.add(opts, '"%s": You can\'t use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.' % f.name)
if f.name.endswith('_'):
@@ -69,8 +69,8 @@ def get_validation_errors(outfile, app=None):
if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.max_length > 255:
e.add(opts, '"%s": %s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
# Check to see if the related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
# Check to see if the related field will clash with any existing
# fields, m2m fields, m2m related objects or related objects
if f.rel:
if f.rel.to not in models.get_models():
e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, f.rel.to))
@@ -87,7 +87,7 @@ def get_validation_errors(outfile, app=None):
e.add(opts, "Accessor for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
if r.name == rel_query_name:
e.add(opts, "Reverse query name for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
for r in rel_opts.many_to_many:
for r in rel_opts.local_many_to_many:
if r.name == rel_name:
e.add(opts, "Accessor for field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
if r.name == rel_query_name:
@@ -104,9 +104,10 @@ def get_validation_errors(outfile, app=None):
if r.get_accessor_name() == rel_query_name:
e.add(opts, "Reverse query name for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))
for i, f in enumerate(opts.many_to_many):
for i, f in enumerate(opts.local_many_to_many):
# Check to see if the related m2m field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
# existing fields, m2m fields, m2m related objects or related
# objects
if f.rel.to not in models.get_models():
e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, f.rel.to))
# it is a string and we could not find the model it refers to
@@ -117,17 +118,17 @@ def get_validation_errors(outfile, app=None):
rel_opts = f.rel.to._meta
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
rel_query_name = f.related_query_name()
# If rel_name is none, there is no reverse accessor.
# (This only occurs for symmetrical m2m relations to self).
# If this is the case, there are no clashes to check for this field, as
# there are no reverse descriptors for this field.
# If rel_name is none, there is no reverse accessor (this only
# occurs for symmetrical m2m relations to self). If this is the
# case, there are no clashes to check for this field, as there are
# no reverse descriptors for this field.
if rel_name is not None:
for r in rel_opts.fields:
if r.name == rel_name:
e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
if r.name == rel_query_name:
e.add(opts, "Reverse query name for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
for r in rel_opts.many_to_many:
for r in rel_opts.local_many_to_many:
if r.name == rel_name:
e.add(opts, "Accessor for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
if r.name == rel_query_name:
@@ -200,7 +201,10 @@ def get_validation_errors(outfile, app=None):
field_name = field_name[1:]
if opts.order_with_respect_to and field_name == '_order':
continue
if '.' in field_name: continue # Skip ordering in the format 'table.field'.
# Skip ordering in the format field1__field2 (FIXME: checking
# this format would be nice, but it's a little fiddly).
if '_' in field_name:
continue
try:
opts.get_field(field_name, many_to_many=False)
except models.FieldDoesNotExist:
@@ -228,5 +232,7 @@ def get_validation_errors(outfile, app=None):
else:
if isinstance(f.rel, models.ManyToManyRel):
e.add(opts, '"unique_together" refers to %s. ManyToManyFields are not supported in unique_together.' % f.name)
if f not in opts.local_fields:
e.add(opts, '"unique_together" refers to %s. This is not in the same model as the unique_together statement.' % f.name)
return len(e.errors)

View File

@@ -165,7 +165,7 @@ class DeserializedObject(object):
# This ensures that the data that is deserialized is literally
# what came from the file, not post-processed by pre_save/save
# methods.
models.Model.save(self.object, raw=True)
models.Model.save_base(self.object, raw=True)
if self.m2m_data and save_m2m:
for accessor_name, object_list in self.m2m_data.items():
setattr(self.object, accessor_name, object_list)