1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Renamed Field.rel attribute to remote_field

Field.rel is now deprecated. Rel objects have now also remote_field
attribute. This means that self == self.remote_field.remote_field.

In addition, made the Rel objects a bit more like Field objects. Still,
marked ManyToManyFields as null=True.
This commit is contained in:
Anssi Kääriäinen
2015-02-26 16:19:17 +02:00
committed by Tim Graham
parent f9c70bb3a1
commit 8f30556329
62 changed files with 601 additions and 598 deletions

View File

@@ -125,7 +125,7 @@ class BaseDatabaseIntrospection(object):
for f in model._meta.local_many_to_many:
# If this is an m2m using an intermediate table,
# we don't need to reset the sequence.
if f.rel.through is None:
if f.remote_field.through is None:
sequence_list.append({'table': f.m2m_db_table(), 'column': None})
return sequence_list

View File

@@ -241,9 +241,9 @@ class BaseDatabaseSchemaEditor(object):
definition += " %s" % col_type_suffix
params.extend(extra_params)
# FK
if field.rel and field.db_constraint:
to_table = field.rel.to._meta.db_table
to_column = field.rel.to._meta.get_field(field.rel.field_name).column
if field.remote_field and field.db_constraint:
to_table = field.remote_field.model._meta.db_table
to_column = field.remote_field.model._meta.get_field(field.remote_field.field_name).column
if self.connection.features.supports_foreign_keys:
self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
elif self.sql_create_inline_fk:
@@ -284,8 +284,8 @@ class BaseDatabaseSchemaEditor(object):
# Make M2M tables
for field in model._meta.local_many_to_many:
if field.rel.through._meta.auto_created:
self.create_model(field.rel.through)
if field.remote_field.through._meta.auto_created:
self.create_model(field.remote_field.through)
def delete_model(self, model):
"""
@@ -293,8 +293,8 @@ class BaseDatabaseSchemaEditor(object):
"""
# Handle auto-created intermediary models
for field in model._meta.local_many_to_many:
if field.rel.through._meta.auto_created:
self.delete_model(field.rel.through)
if field.remote_field.through._meta.auto_created:
self.delete_model(field.remote_field.through)
# Delete the table
self.execute(self.sql_delete_table % {
@@ -377,8 +377,8 @@ class BaseDatabaseSchemaEditor(object):
table instead (for M2M fields)
"""
# Special-case implicit M2M tables
if field.many_to_many and field.rel.through._meta.auto_created:
return self.create_model(field.rel.through)
if field.many_to_many and field.remote_field.through._meta.auto_created:
return self.create_model(field.remote_field.through)
# Get the column's definition
definition, params = self.column_sql(model, field, include_default=True)
# It might not actually have a column behind it
@@ -409,7 +409,7 @@ class BaseDatabaseSchemaEditor(object):
if field.db_index and not field.unique:
self.deferred_sql.append(self._create_index_sql(model, [field]))
# Add any FK constraints later
if field.rel and self.connection.features.supports_foreign_keys and field.db_constraint:
if field.remote_field and self.connection.features.supports_foreign_keys and field.db_constraint:
self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
# Reset connection if required
if self.connection.features.connection_persists_old_columns:
@@ -421,13 +421,13 @@ class BaseDatabaseSchemaEditor(object):
but for M2Ms may involve deleting a table.
"""
# Special-case implicit M2M tables
if field.many_to_many and field.rel.through._meta.auto_created:
return self.delete_model(field.rel.through)
if field.many_to_many and field.remote_field.through._meta.auto_created:
return self.delete_model(field.remote_field.through)
# It might not actually have a column behind it
if field.db_parameters(connection=self.connection)['type'] is None:
return
# Drop any FK constraints, MySQL requires explicit deletion
if field.rel:
if field.remote_field:
fk_names = self._constraint_names(model, [field.column], foreign_key=True)
for fk_name in fk_names:
self.execute(self._delete_constraint_sql(self.sql_delete_fk, model, fk_name))
@@ -454,21 +454,21 @@ class BaseDatabaseSchemaEditor(object):
old_type = old_db_params['type']
new_db_params = new_field.db_parameters(connection=self.connection)
new_type = new_db_params['type']
if (old_type is None and old_field.rel is None) or (new_type is None and new_field.rel is None):
if (old_type is None and old_field.remote_field is None) or (new_type is None and new_field.remote_field is None):
raise ValueError(
"Cannot alter field %s into %s - they do not properly define "
"db_type (are you using PostGIS 1.5 or badly-written custom "
"fields?)" % (old_field, new_field),
)
elif old_type is None and new_type is None and (
old_field.rel.through and new_field.rel.through and
old_field.rel.through._meta.auto_created and
new_field.rel.through._meta.auto_created):
old_field.remote_field.through and new_field.remote_field.through and
old_field.remote_field.through._meta.auto_created and
new_field.remote_field.through._meta.auto_created):
return self._alter_many_to_many(model, old_field, new_field, strict)
elif old_type is None and new_type is None and (
old_field.rel.through and new_field.rel.through and
not old_field.rel.through._meta.auto_created and
not new_field.rel.through._meta.auto_created):
old_field.remote_field.through and new_field.remote_field.through and
not old_field.remote_field.through._meta.auto_created and
not new_field.remote_field.through._meta.auto_created):
# Both sides have through models; this is a no-op.
return
elif old_type is None or new_type is None:
@@ -487,7 +487,7 @@ class BaseDatabaseSchemaEditor(object):
# Drop any FK constraints, we'll remake them later
fks_dropped = set()
if old_field.rel and old_field.db_constraint:
if old_field.remote_field and old_field.db_constraint:
fk_names = self._constraint_names(model, [old_field.column], foreign_key=True)
if strict and len(fk_names) != 1:
raise ValueError("Found wrong number (%s) of foreign key constraints for %s.%s" % (
@@ -707,8 +707,8 @@ class BaseDatabaseSchemaEditor(object):
}
)
# Does it have a foreign key?
if (new_field.rel and
(fks_dropped or not old_field.rel or not old_field.db_constraint) and
if (new_field.remote_field and
(fks_dropped or not old_field.remote_field or not old_field.db_constraint) and
new_field.db_constraint):
self.execute(self._create_fk_sql(model, new_field, "_fk_%(to_table)s_%(to_column)s"))
# Rebuild FKs that pointed to us if we previously had to drop them
@@ -766,22 +766,22 @@ class BaseDatabaseSchemaEditor(object):
Alters M2Ms to repoint their to= endpoints.
"""
# Rename the through table
if old_field.rel.through._meta.db_table != new_field.rel.through._meta.db_table:
self.alter_db_table(old_field.rel.through, old_field.rel.through._meta.db_table,
new_field.rel.through._meta.db_table)
if old_field.remote_field.through._meta.db_table != new_field.remote_field.through._meta.db_table:
self.alter_db_table(old_field.remote_field.through, old_field.remote_field.through._meta.db_table,
new_field.remote_field.through._meta.db_table)
# Repoint the FK to the other side
self.alter_field(
new_field.rel.through,
new_field.remote_field.through,
# We need the field that points to the target model, so we can tell alter_field to change it -
# this is m2m_reverse_field_name() (as opposed to m2m_field_name, which points to our model)
old_field.rel.through._meta.get_field(old_field.m2m_reverse_field_name()),
new_field.rel.through._meta.get_field(new_field.m2m_reverse_field_name()),
old_field.remote_field.through._meta.get_field(old_field.m2m_reverse_field_name()),
new_field.remote_field.through._meta.get_field(new_field.m2m_reverse_field_name()),
)
self.alter_field(
new_field.rel.through,
new_field.remote_field.through,
# for self-referential models we need to alter field from the other end too
old_field.rel.through._meta.get_field(old_field.m2m_field_name()),
new_field.rel.through._meta.get_field(new_field.m2m_field_name()),
old_field.remote_field.through._meta.get_field(old_field.m2m_field_name()),
new_field.remote_field.through._meta.get_field(new_field.m2m_field_name()),
)
def _create_index_name(self, model, column_names, suffix=""):
@@ -860,8 +860,8 @@ class BaseDatabaseSchemaEditor(object):
def _create_fk_sql(self, model, field, suffix):
from_table = model._meta.db_table
from_column = field.column
to_table = field.related_field.model._meta.db_table
to_column = field.related_field.column
to_table = field.target_field.model._meta.db_table
to_column = field.target_field.column
suffix = suffix % {
"to_table": to_table,
"to_column": to_column,

View File

@@ -14,7 +14,7 @@ class DatabaseValidation(BaseDatabaseValidation):
errors = super(DatabaseValidation, self).check_field(field, **kwargs)
# Ignore any related fields.
if getattr(field, 'rel', None) is None:
if getattr(field, 'remote_field', None) is None:
field_type = field.db_type(connection)
# Ignore any non-concrete fields

View File

@@ -346,7 +346,7 @@ WHEN (new.%(col_name)s IS NULL)
# continue to loop
break
for f in model._meta.many_to_many:
if not f.rel.through:
if not f.remote_field.through:
table_name = self.quote_name(f.m2m_db_table())
sequence_name = self._get_sequence_name(f.m2m_db_table())
column_name = self.quote_name('id')

View File

@@ -172,7 +172,7 @@ class DatabaseOperations(BaseDatabaseOperations):
)
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
if not f.rel.through:
if not f.remote_field.through:
output.append(
"%s setval(pg_get_serial_sequence('%s','%s'), "
"coalesce(max(%s), 1), max(%s) %s null) %s %s;" % (

View File

@@ -118,8 +118,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
del body[field.name]
del mapping[field.column]
# Remove any implicit M2M tables
if field.many_to_many and field.rel.through._meta.auto_created:
return self.delete_model(field.rel.through)
if field.many_to_many and field.remote_field.through._meta.auto_created:
return self.delete_model(field.remote_field.through)
# Work inside a new app registry
apps = Apps()
@@ -215,8 +215,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
table instead (for M2M fields)
"""
# Special-case implicit M2M tables
if field.many_to_many and field.rel.through._meta.auto_created:
return self.create_model(field.rel.through)
if field.many_to_many and field.remote_field.through._meta.auto_created:
return self.create_model(field.remote_field.through)
self._remake_table(model, create_fields=[field])
def remove_field(self, model, field):
@@ -227,8 +227,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
# M2M fields are a special case
if field.many_to_many:
# For implicit M2M tables, delete the auto-created table
if field.rel.through._meta.auto_created:
self.delete_model(field.rel.through)
if field.remote_field.through._meta.auto_created:
self.delete_model(field.remote_field.through)
# For explicit "through" M2M fields, do nothing
# For everything else, remake.
else:
@@ -263,25 +263,25 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
"""
Alters M2Ms to repoint their to= endpoints.
"""
if old_field.rel.through._meta.db_table == new_field.rel.through._meta.db_table:
if old_field.remote_field.through._meta.db_table == new_field.remote_field.through._meta.db_table:
# The field name didn't change, but some options did; we have to propagate this altering.
self._remake_table(
old_field.rel.through,
old_field.remote_field.through,
alter_fields=[(
# We need the field that points to the target model, so we can tell alter_field to change it -
# this is m2m_reverse_field_name() (as opposed to m2m_field_name, which points to our model)
old_field.rel.through._meta.get_field(old_field.m2m_reverse_field_name()),
new_field.rel.through._meta.get_field(new_field.m2m_reverse_field_name()),
old_field.remote_field.through._meta.get_field(old_field.m2m_reverse_field_name()),
new_field.remote_field.through._meta.get_field(new_field.m2m_reverse_field_name()),
)],
override_uniques=(new_field.m2m_field_name(), new_field.m2m_reverse_field_name()),
)
return
# Make a new through table
self.create_model(new_field.rel.through)
self.create_model(new_field.remote_field.through)
# Copy the data across
self.execute("INSERT INTO %s (%s) SELECT %s FROM %s" % (
self.quote_name(new_field.rel.through._meta.db_table),
self.quote_name(new_field.remote_field.through._meta.db_table),
', '.join([
"id",
new_field.m2m_column_name(),
@@ -292,7 +292,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
old_field.m2m_column_name(),
old_field.m2m_reverse_name(),
]),
self.quote_name(old_field.rel.through._meta.db_table),
self.quote_name(old_field.remote_field.through._meta.db_table),
))
# Delete the old through table
self.delete_model(old_field.rel.through)
self.delete_model(old_field.remote_field.through)

View File

@@ -78,7 +78,7 @@ class MigrationAutodetector(object):
fields_def = []
for name, field in fields:
deconstruction = self.deep_deconstruct(field)
if field.rel and field.rel.to:
if field.remote_field and field.remote_field.model:
del deconstruction[2]['to']
fields_def.append(deconstruction)
return fields_def
@@ -163,11 +163,11 @@ class MigrationAutodetector(object):
old_model_state = self.from_state.models[app_label, old_model_name]
for field_name, field in old_model_state.fields:
old_field = self.old_apps.get_model(app_label, old_model_name)._meta.get_field(field_name)
if (hasattr(old_field, "rel") and getattr(old_field.rel, "through", None)
and not old_field.rel.through._meta.auto_created):
if (hasattr(old_field, "remote_field") and getattr(old_field.remote_field, "through", None)
and not old_field.remote_field.through._meta.auto_created):
through_key = (
old_field.rel.through._meta.app_label,
old_field.rel.through._meta.model_name,
old_field.remote_field.through._meta.app_label,
old_field.remote_field.through._meta.model_name,
)
self.through_users[through_key] = (app_label, old_model_name, field_name)
@@ -460,20 +460,20 @@ class MigrationAutodetector(object):
related_fields = {}
primary_key_rel = None
for field in model_opts.local_fields:
if field.rel:
if field.rel.to:
if field.remote_field:
if field.remote_field.model:
if field.primary_key:
primary_key_rel = field.rel.to
elif not field.rel.parent_link:
primary_key_rel = field.remote_field.model
elif not field.remote_field.parent_link:
related_fields[field.name] = field
# through will be none on M2Ms on swapped-out models;
# we can treat lack of through as auto_created=True, though.
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
related_fields[field.name] = field
for field in model_opts.local_many_to_many:
if field.rel.to:
if field.remote_field.model:
related_fields[field.name] = field
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
related_fields[field.name] = field
# Are there unique/index_together to defer?
unique_together = model_state.options.pop('unique_together', None)
@@ -522,13 +522,13 @@ class MigrationAutodetector(object):
dep_app_label = "__setting__"
dep_object_name = swappable_setting
else:
dep_app_label = field.rel.to._meta.app_label
dep_object_name = field.rel.to._meta.object_name
dep_app_label = field.remote_field.model._meta.app_label
dep_object_name = field.remote_field.model._meta.object_name
dependencies = [(dep_app_label, dep_object_name, None, True)]
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
dependencies.append((
field.rel.through._meta.app_label,
field.rel.through._meta.object_name,
field.remote_field.through._meta.app_label,
field.remote_field.through._meta.object_name,
None,
True
))
@@ -639,17 +639,17 @@ class MigrationAutodetector(object):
# Gather related fields
related_fields = {}
for field in model._meta.local_fields:
if field.rel:
if field.rel.to:
if field.remote_field:
if field.remote_field.model:
related_fields[field.name] = field
# through will be none on M2Ms on swapped-out models;
# we can treat lack of through as auto_created=True, though.
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
related_fields[field.name] = field
for field in model._meta.local_many_to_many:
if field.rel.to:
if field.remote_field.model:
related_fields[field.name] = field
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
related_fields[field.name] = field
# Generate option removal first
unique_together = model_state.options.pop('unique_together', None)
@@ -736,7 +736,7 @@ class MigrationAutodetector(object):
for rem_app_label, rem_model_name, rem_field_name in sorted(self.old_field_keys - self.new_field_keys):
if rem_app_label == app_label and rem_model_name == model_name:
old_field_dec = self.deep_deconstruct(old_model_state.get_field_by_name(rem_field_name))
if field.rel and field.rel.to and 'to' in old_field_dec[2]:
if field.remote_field and field.remote_field.model and 'to' in old_field_dec[2]:
old_rel_to = old_field_dec[2]['to']
if old_rel_to in self.renamed_models_rel:
old_field_dec[2]['to'] = self.renamed_models_rel[old_rel_to]
@@ -766,20 +766,20 @@ class MigrationAutodetector(object):
field = self.new_apps.get_model(app_label, model_name)._meta.get_field(field_name)
# Fields that are foreignkeys/m2ms depend on stuff
dependencies = []
if field.rel and field.rel.to:
if field.remote_field and field.remote_field.model:
# Account for FKs to swappable models
swappable_setting = getattr(field, 'swappable_setting', None)
if swappable_setting is not None:
dep_app_label = "__setting__"
dep_object_name = swappable_setting
else:
dep_app_label = field.rel.to._meta.app_label
dep_object_name = field.rel.to._meta.object_name
dep_app_label = field.remote_field.model._meta.app_label
dep_object_name = field.remote_field.model._meta.object_name
dependencies = [(dep_app_label, dep_object_name, None, True)]
if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created:
dependencies.append((
field.rel.through._meta.app_label,
field.rel.through._meta.object_name,
field.remote_field.through._meta.app_label,
field.remote_field.through._meta.object_name,
None,
True,
))
@@ -838,13 +838,13 @@ class MigrationAutodetector(object):
new_field = self.new_apps.get_model(app_label, model_name)._meta.get_field(field_name)
# Implement any model renames on relations; these are handled by RenameModel
# so we need to exclude them from the comparison
if hasattr(new_field, "rel") and getattr(new_field.rel, "to", None):
if hasattr(new_field, "remote_field") and getattr(new_field.remote_field, "model", None):
rename_key = (
new_field.rel.to._meta.app_label,
new_field.rel.to._meta.model_name,
new_field.remote_field.model._meta.app_label,
new_field.remote_field.model._meta.model_name,
)
if rename_key in self.renamed_models:
new_field.rel.to = old_field.rel.to
new_field.remote_field.model = old_field.remote_field.model
old_field_dec = self.deep_deconstruct(old_field)
new_field_dec = self.deep_deconstruct(new_field)
if old_field_dec != new_field_dec:

View File

@@ -191,11 +191,11 @@ class AlterField(Operation):
# If the field is a relatedfield with an unresolved rel.to, just
# set it equal to the other field side. Bandaid fix for AlterField
# migrations that are part of a RenameModel change.
if from_field.rel and from_field.rel.to:
if isinstance(from_field.rel.to, six.string_types):
from_field.rel.to = to_field.rel.to
elif to_field.rel and isinstance(to_field.rel.to, six.string_types):
to_field.rel.to = from_field.rel.to
if from_field.remote_field and from_field.remote_field.model:
if isinstance(from_field.remote_field.model, six.string_types):
from_field.remote_field.model = to_field.remote_field.model
elif to_field.remote_field and isinstance(to_field.remote_field.model, six.string_types):
to_field.remote_field.model = from_field.remote_field.model
if not self.preserve_default:
to_field.default = self.field.default
schema_editor.alter_field(from_model, from_field, to_field)

View File

@@ -74,9 +74,9 @@ class CreateModel(Operation):
strings_to_check.append(base.split(".")[-1])
# Check we have no FKs/M2Ms with it
for fname, field in self.fields:
if field.rel:
if isinstance(field.rel.to, six.string_types):
strings_to_check.append(field.rel.to.split(".")[-1])
if field.remote_field:
if isinstance(field.remote_field.model, six.string_types):
strings_to_check.append(field.remote_field.model.split(".")[-1])
# Now go over all the strings and compare them
for string in strings_to_check:
if string.lower() == name.lower():
@@ -181,7 +181,7 @@ class RenameModel(Operation):
for name, field in state.models[related_key].fields:
if name == related_object.field.name:
field = field.clone()
field.rel.to = "%s.%s" % (app_label, self.new_name)
field.remote_field.model = "%s.%s" % (app_label, self.new_name)
new_fields.append((name, field))
state.models[related_key].fields = new_fields
state.reload_model(*related_key)
@@ -220,11 +220,11 @@ class RenameModel(Operation):
fields = zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many)
for (old_field, new_field) in fields:
# Skip self-referential fields as these are renamed above.
if new_field.model == new_field.related_model or not new_field.rel.through._meta.auto_created:
if new_field.model == new_field.related_model or not new_field.remote_field.through._meta.auto_created:
continue
# Rename the M2M table that's based on this model's name.
old_m2m_model = old_field.rel.through
new_m2m_model = new_field.rel.through
old_m2m_model = old_field.remote_field.through
new_m2m_model = new_field.remote_field.through
schema_editor.alter_db_table(
new_m2m_model,
old_m2m_model._meta.db_table,
@@ -296,11 +296,11 @@ class AlterModelTable(Operation):
)
# Rename M2M fields whose name is based on this model's db_table
for (old_field, new_field) in zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many):
if new_field.rel.through._meta.auto_created:
if new_field.remote_field.through._meta.auto_created:
schema_editor.alter_db_table(
new_field.rel.through,
old_field.rel.through._meta.db_table,
new_field.rel.through._meta.db_table,
new_field.remote_field.through,
old_field.remote_field.through._meta.db_table,
new_field.remote_field.through._meta.db_table,
)
def database_backwards(self, app_label, schema_editor, from_state, to_state):

View File

@@ -230,15 +230,15 @@ class MigrationOptimizer(object):
def reduce_create_model_add_field(self, operation, other, in_between):
if operation.name_lower == other.model_name_lower:
# Don't allow optimizations of FKs through models they reference
if hasattr(other.field, "rel") and other.field.rel:
if hasattr(other.field, "remote_field") and other.field.remote_field:
for between in in_between:
# Check that it doesn't point to the model
app_label, object_name = self.model_to_key(other.field.rel.to)
app_label, object_name = self.model_to_key(other.field.remote_field.model)
if between.references_model(object_name, app_label):
return None
# Check that it's not through the model
if getattr(other.field.rel, "through", None):
app_label, object_name = self.model_to_key(other.field.rel.through)
if getattr(other.field.remote_field, "through", None):
app_label, object_name = self.model_to_key(other.field.remote_field.through)
if between.references_model(object_name, app_label):
return None
# OK, that's fine

View File

@@ -94,9 +94,9 @@ class ProjectState(object):
model_state = self.models[(app_label, model_name)]
for name, field in model_state.fields:
if field.is_relation:
if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT:
if field.remote_field.model == RECURSIVE_RELATIONSHIP_CONSTANT:
continue
rel_app_label, rel_model_name = _get_app_label_and_model_name(field.rel.to, app_label)
rel_app_label, rel_model_name = _get_app_label_and_model_name(field.remote_field.model, app_label)
related_models.add((rel_app_label, rel_model_name.lower()))
# Unregister all related models
@@ -328,7 +328,7 @@ class ModelState(object):
# Deconstruct the fields
fields = []
for field in model._meta.local_fields:
if getattr(field, "rel", None) and exclude_rels:
if getattr(field, "remote_field", None) and exclude_rels:
continue
if isinstance(field, OrderWrt):
continue

View File

@@ -199,7 +199,7 @@ class ModelBase(type):
# Locate OneToOneField instances.
for field in base._meta.local_fields:
if isinstance(field, OneToOneField):
parent_links[field.rel.to] = field
parent_links[field.remote_field.model] = field
# Do the appropriate setup for any model parents.
for base in parents:
@@ -307,19 +307,19 @@ class ModelBase(type):
# certain it has been created
def make_foreign_order_accessors(field, model, cls):
setattr(
field.rel.to,
field.remote_field.model,
'get_%s_order' % cls.__name__.lower(),
curry(method_get_order, cls)
)
setattr(
field.rel.to,
field.remote_field.model,
'set_%s_order' % cls.__name__.lower(),
curry(method_set_order, cls)
)
add_lazy_relation(
cls,
opts.order_with_respect_to,
opts.order_with_respect_to.rel.to,
opts.order_with_respect_to.remote_field.model,
make_foreign_order_accessors
)
@@ -382,7 +382,7 @@ class Model(six.with_metaclass(ModelBase)):
setattr(self, field.attname, val)
kwargs.pop(field.name, None)
# Maintain compatibility with existing calls.
if isinstance(field.rel, ManyToOneRel):
if isinstance(field.remote_field, ManyToOneRel):
kwargs.pop(field.attname, None)
# Now we're left with the unprocessed fields that *must* come from
@@ -399,7 +399,7 @@ class Model(six.with_metaclass(ModelBase)):
# This field will be populated on request.
continue
if kwargs:
if isinstance(field.rel, ForeignObjectRel):
if isinstance(field.remote_field, ForeignObjectRel):
try:
# Assume object instance was passed in.
rel_obj = kwargs.pop(field.name)
@@ -879,7 +879,7 @@ class Model(six.with_metaclass(ModelBase)):
def prepare_database_save(self, field):
if self.pk is None:
raise ValueError("Unsaved model instance %r cannot be used in an ORM query." % self)
return getattr(self, field.rel.field_name)
return getattr(self, field.remote_field.field_name)
def clean(self):
"""
@@ -1238,20 +1238,20 @@ class Model(six.with_metaclass(ModelBase)):
fields = cls._meta.local_many_to_many
# Skip when the target model wasn't found.
fields = (f for f in fields if isinstance(f.rel.to, ModelBase))
fields = (f for f in fields if isinstance(f.remote_field.model, ModelBase))
# Skip when the relationship model wasn't found.
fields = (f for f in fields if isinstance(f.rel.through, ModelBase))
fields = (f for f in fields if isinstance(f.remote_field.through, ModelBase))
for f in fields:
signature = (f.rel.to, cls, f.rel.through)
signature = (f.remote_field.model, cls, f.remote_field.through)
if signature in seen_intermediary_signatures:
errors.append(
checks.Error(
"The model has two many-to-many relations through "
"the intermediate model '%s.%s'." % (
f.rel.through._meta.app_label,
f.rel.through._meta.object_name
f.remote_field.through._meta.app_label,
f.remote_field.through._meta.object_name
),
hint=None,
obj=cls,
@@ -1448,7 +1448,7 @@ class Model(six.with_metaclass(ModelBase)):
)
)
else:
if isinstance(field.rel, models.ManyToManyRel):
if isinstance(field.remote_field, models.ManyToManyRel):
errors.append(
checks.Error(
"'%s' refers to a ManyToManyField '%s', but "
@@ -1595,7 +1595,7 @@ class Model(six.with_metaclass(ModelBase)):
for f in cls._meta.local_many_to_many:
# Check if auto-generated name for the M2M field is too long
# for the database.
for m2m in f.rel.through._meta.local_fields:
for m2m in f.remote_field.through._meta.local_fields:
_, rel_name = m2m.get_attname_column()
if (m2m.db_column is None and rel_name is not None
and len(rel_name) > allowed_len):
@@ -1624,7 +1624,7 @@ class Model(six.with_metaclass(ModelBase)):
def method_set_order(ordered_obj, self, id_list, using=None):
if using is None:
using = DEFAULT_DB_ALIAS
rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.remote_field.field_name)
order_name = ordered_obj._meta.order_with_respect_to.name
# FIXME: It would be nice if there was an "update many" version of update
# for situations like this.
@@ -1634,7 +1634,7 @@ def method_set_order(ordered_obj, self, id_list, using=None):
def method_get_order(ordered_obj, self):
rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.remote_field.field_name)
order_name = ordered_obj._meta.order_with_respect_to.name
pk_name = ordered_obj._meta.pk.name
return [r[pk_name] for r in

View File

@@ -14,7 +14,7 @@ class ProtectedError(IntegrityError):
def CASCADE(collector, field, sub_objs, using):
collector.collect(sub_objs, source=field.rel.to,
collector.collect(sub_objs, source=field.remote_field.model,
source_attr=field.name, nullable=field.null)
if field.null and not connections[using].features.can_defer_constraint_checks:
collector.add_field_update(field, None, sub_objs)
@@ -23,7 +23,7 @@ def CASCADE(collector, field, sub_objs, using):
def PROTECT(collector, field, sub_objs, using):
raise ProtectedError("Cannot delete some instances of model '%s' because "
"they are referenced through a protected foreign key: '%s.%s'" % (
field.rel.to.__name__, sub_objs[0].__class__.__name__, field.name
field.remote_field.model.__name__, sub_objs[0].__class__.__name__, field.name
),
sub_objs
)
@@ -136,7 +136,7 @@ class Collector(object):
skipping parent -> child -> parent chain preventing fast delete of
the child.
"""
if from_field and from_field.rel.on_delete is not CASCADE:
if from_field and from_field.remote_field.on_delete is not CASCADE:
return False
if not (hasattr(objs, 'model') and hasattr(objs, '_raw_delete')):
return False
@@ -153,7 +153,7 @@ class Collector(object):
# Foreign keys pointing to this model, both from m2m and other
# models.
for related in get_candidate_relations_to_delete(opts):
if related.field.rel.on_delete is not DO_NOTHING:
if related.field.remote_field.on_delete is not DO_NOTHING:
return False
for field in model._meta.virtual_fields:
if hasattr(field, 'bulk_related_objects'):
@@ -214,14 +214,13 @@ class Collector(object):
# object instance.
parent_objs = [getattr(obj, ptr.name) for obj in new_objs]
self.collect(parent_objs, source=model,
source_attr=ptr.rel.related_name,
source_attr=ptr.remote_field.related_name,
collect_related=False,
reverse_dependency=True)
if collect_related:
for related in get_candidate_relations_to_delete(model._meta):
field = related.field
if field.rel.on_delete == DO_NOTHING:
if field.remote_field.on_delete == DO_NOTHING:
continue
batches = self.get_del_batches(new_objs, field)
for batch in batches:
@@ -229,14 +228,14 @@ class Collector(object):
if self.can_fast_delete(sub_objs, from_field=field):
self.fast_deletes.append(sub_objs)
elif sub_objs:
field.rel.on_delete(self, field, sub_objs, self.using)
field.remote_field.on_delete(self, field, sub_objs, self.using)
for field in model._meta.virtual_fields:
if hasattr(field, 'bulk_related_objects'):
# Its something like generic foreign key.
sub_objs = field.bulk_related_objects(new_objs, self.using)
self.collect(sub_objs,
source=model,
source_attr=field.rel.related_name,
source_attr=field.remote_field.related_name,
nullable=True)
def related_objects(self, related, objs):

View File

@@ -23,6 +23,7 @@ from django.utils.duration import duration_string
from django.utils.functional import cached_property, curry, total_ordering, Promise
from django.utils.text import capfirst
from django.utils import timezone
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import (smart_text, force_text, force_bytes,
python_2_unicode_compatible)
@@ -146,8 +147,8 @@ class Field(RegisterLookupMixin):
self.primary_key = primary_key
self.max_length, self._unique = max_length, unique
self.blank, self.null = blank, null
self.rel = rel
self.is_relation = self.rel is not None
self.remote_field = rel
self.is_relation = self.remote_field is not None
self.default = default
self.editable = editable
self.serialize = serialize
@@ -240,6 +241,13 @@ class Field(RegisterLookupMixin):
else:
return []
@property
def rel(self):
warnings.warn(
"Usage of field.rel has been deprecated. Use field.remote_field instead.",
RemovedInDjango21Warning, 2)
return self.remote_field
def _check_choices(self):
if self.choices:
if (isinstance(self.choices, six.string_types) or
@@ -468,10 +476,10 @@ class Field(RegisterLookupMixin):
# We don't have to deepcopy very much here, since most things are not
# intended to be altered after initial creation.
obj = copy.copy(self)
if self.rel:
obj.rel = copy.copy(self.rel)
if hasattr(self.rel, 'field') and self.rel.field is self:
obj.rel.field = obj
if self.remote_field:
obj.remote_field = copy.copy(self.remote_field)
if hasattr(self.remote_field, 'field') and self.remote_field.field is self:
obj.remote_field.field = obj
memodict[id(self)] = obj
return obj
@@ -811,10 +819,10 @@ class Field(RegisterLookupMixin):
not blank_defined else [])
if self.choices:
return first_choice + choices
rel_model = self.rel.to
rel_model = self.remote_field.model
limit_choices_to = limit_choices_to or self.get_limit_choices_to()
if hasattr(self.rel, 'get_related_field'):
lst = [(getattr(x, self.rel.get_related_field().attname),
if hasattr(self.remote_field, 'get_related_field'):
lst = [(getattr(x, self.remote_field.get_related_field().attname),
smart_text(x))
for x in rel_model._default_manager.complex_filter(
limit_choices_to)]

File diff suppressed because it is too large Load Diff

View File

@@ -26,8 +26,8 @@ def get_normalized_value(value, lhs):
# Account for one-to-one relations when sent a different model
sources = lhs.output_field.get_path_info()[-1].target_fields
for source in sources:
while not isinstance(value, source.model) and source.rel:
source = source.rel.to._meta.get_field(source.rel.field_name)
while not isinstance(value, source.model) and source.remote_field:
source = source.remote_field.model._meta.get_field(source.remote_field.field_name)
value_list.append(getattr(value, source.attname))
return tuple(value_list)
if not isinstance(value, tuple):

View File

@@ -308,9 +308,9 @@ class Options(object):
# ideally, we'd just ask for field.related_model. However, related_model
# is a cached property, and all the models haven't been loaded yet, so
# we need to make sure we don't cache a string reference.
if field.is_relation and hasattr(field.rel, 'to') and field.rel.to:
if field.is_relation and hasattr(field.remote_field, 'model') and field.remote_field.model:
try:
field.rel.to._meta._expire_cache(forward=False)
field.remote_field.model._meta._expire_cache(forward=False)
except AttributeError:
pass
self._expire_cache()
@@ -393,7 +393,7 @@ class Options(object):
is_not_an_m2m_field = lambda f: not (f.is_relation and f.many_to_many)
is_not_a_generic_relation = lambda f: not (f.is_relation and f.one_to_many)
is_not_a_generic_foreign_key = lambda f: not (
f.is_relation and f.many_to_one and not (hasattr(f.rel, 'to') and f.rel.to)
f.is_relation and f.many_to_one and not (hasattr(f.remote_field, 'model') and f.remote_field.model)
)
return make_immutable_fields_list(
"fields",
@@ -592,8 +592,8 @@ class Options(object):
children = chain.from_iterable(c._relation_tree
for c in self.concrete_model._meta.proxied_children
if c is not self)
relations = (f.rel for f in children
if include_hidden or not f.rel.field.rel.is_hidden())
relations = (f.remote_field for f in children
if include_hidden or not f.remote_field.field.remote_field.is_hidden())
fields = chain(fields, relations)
return list(fields)
@@ -690,8 +690,8 @@ class Options(object):
if f.is_relation and f.related_model is not None
)
for f in fields_with_relations:
if not isinstance(f.rel.to, six.string_types):
related_objects_graph[f.rel.to._meta].append(f)
if not isinstance(f.remote_field.model, six.string_types):
related_objects_graph[f.remote_field.model._meta].append(f)
for model in all_models:
# Set the relation_tree using the internal __dict__. In this way
@@ -804,8 +804,8 @@ class Options(object):
for field in all_fields:
# If hidden fields should be included or the relation is not
# intentionally hidden, add to the fields dict.
if include_hidden or not field.rel.hidden:
fields.append(field.rel)
if include_hidden or not field.remote_field.hidden:
fields.append(field.remote_field)
if forward:
fields.extend(

View File

@@ -1645,12 +1645,12 @@ class RelatedPopulator(object):
reverse = klass_info['reverse']
self.reverse_cache_name = None
if reverse:
self.cache_name = field.rel.get_cache_name()
self.cache_name = field.remote_field.get_cache_name()
self.reverse_cache_name = field.get_cache_name()
else:
self.cache_name = field.get_cache_name()
if field.unique:
self.reverse_cache_name = field.rel.get_cache_name()
self.reverse_cache_name = field.remote_field.get_cache_name()
def get_deferred_cls(self, klass_info, init_list):
model_cls = klass_info['model']

View File

@@ -181,9 +181,9 @@ def select_related_descend(field, restricted, requested, load_fields, reverse=Fa
* load_fields - the set of fields to be loaded on this model
* reverse - boolean, True if we are checking a reverse select related
"""
if not field.rel:
if not field.remote_field:
return False
if field.rel.parent_link and not reverse:
if field.remote_field.parent_link and not reverse:
return False
if restricted:
if reverse and field.related_query_name() not in requested:

View File

@@ -676,7 +676,7 @@ class SQLCompiler(object):
only_load.get(field_model)):
continue
klass_info = {
'model': f.rel.to,
'model': f.remote_field.model,
'field': f,
'reverse': False,
'from_parent': False,
@@ -686,13 +686,13 @@ class SQLCompiler(object):
_, _, _, joins, _ = self.query.setup_joins(
[f.name], opts, root_alias)
alias = joins[-1]
columns = self.get_default_columns(start_alias=alias, opts=f.rel.to._meta)
columns = self.get_default_columns(start_alias=alias, opts=f.remote_field.model._meta)
for col in columns:
select_fields.append(len(select))
select.append((col, None))
klass_info['select_fields'] = select_fields
next_klass_infos = self.get_related_selections(
select, f.rel.to._meta, alias, cur_depth + 1, next, restricted)
select, f.remote_field.model._meta, alias, cur_depth + 1, next, restricted)
get_related_klass_infos(klass_info, next_klass_infos)
if restricted:
@@ -1003,7 +1003,7 @@ class SQLUpdateCompiler(SQLCompiler):
if val.contains_aggregate:
raise FieldError("Aggregate functions are not allowed in this query")
elif hasattr(val, 'prepare_database_save'):
if field.rel:
if field.remote_field:
val = val.prepare_database_save(field)
else:
raise TypeError("Database is trying to update a relational field "

View File

@@ -608,7 +608,7 @@ class Query(object):
if is_reverse_o2o(source):
cur_model = source.related_model
else:
cur_model = source.rel.to
cur_model = source.remote_field.model
opts = cur_model._meta
# Even if we're "just passing through" this model, we must add
# both the current model's pk and the related reference field
@@ -1303,7 +1303,7 @@ class Query(object):
opts = int_model._meta
else:
final_field = opts.parents[int_model]
targets = (final_field.rel.get_related_field(),)
targets = (final_field.remote_field.get_related_field(),)
opts = int_model._meta
path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
cur_names_with_path[1].append(