Skip to content

Commit

Permalink
initial fix for 22534, needs tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bendavis78 committed Apr 30, 2014
1 parent b2514c0 commit cc70dd0
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions django/db/models/fields/related.py
Expand Up @@ -117,6 +117,8 @@ def _check_relation_model_exists(self):
return [] return []


def _check_referencing_to_swapped_model(self): def _check_referencing_to_swapped_model(self):
if not self.swappable_setting:
return []
if (self.rel.to not in apps.get_models() and if (self.rel.to not in apps.get_models() and
not isinstance(self.rel.to, six.string_types) and not isinstance(self.rel.to, six.string_types) and
self.rel.to._meta.swapped): self.rel.to._meta.swapped):
Expand Down Expand Up @@ -270,6 +272,26 @@ def resolve_related_class(field, model, cls):
else: else:
self.do_related_class(other, cls) self.do_related_class(other, cls)


@property
def swappable(self):
"""
Boolean indicating whether or not this field should point to the
swapped model if that model is swappable.
"""
# If the "to" model is a string that points to a swappable model, then
# by default it will always point to the swapped model. If the "to"
# model is a reference to the model class itself, it is assumed that it
# should not point to the swapped model. This behavior can be
# explicitly controlled during initialization by passing
# ``swappable=False`` to never reference a swapped model, or
# ``swappable=True`` to always reference a swapped model.
if self._swappable is not None:
return self._swappable
if isinstance(self.rel.to, six.string_types):
to_model = apps.get_model(self.rel.to)
return bool(to_model._meta.swappable)
return False

@property @property
def swappable_setting(self): def swappable_setting(self):
""" """
Expand Down Expand Up @@ -1302,10 +1324,10 @@ class ForeignObject(RelatedField):
generate_reverse_relation = True generate_reverse_relation = True
related_accessor_class = ForeignRelatedObjectsDescriptor related_accessor_class = ForeignRelatedObjectsDescriptor


def __init__(self, to, from_fields, to_fields, swappable=True, **kwargs): def __init__(self, to, from_fields, to_fields, swappable=None, **kwargs):
self.from_fields = from_fields self.from_fields = from_fields
self.to_fields = to_fields self.to_fields = to_fields
self.swappable = swappable self._swappable = swappable


if 'rel' not in kwargs: if 'rel' not in kwargs:
kwargs['rel'] = ForeignObjectRel( kwargs['rel'] = ForeignObjectRel(
Expand Down Expand Up @@ -1854,7 +1876,7 @@ def set_managed(field, model, cls):
class ManyToManyField(RelatedField): class ManyToManyField(RelatedField):
description = _("Many-to-many relationship") description = _("Many-to-many relationship")


def __init__(self, to, db_constraint=True, swappable=True, **kwargs): def __init__(self, to, db_constraint=True, swappable=None, **kwargs):
try: try:
to._meta to._meta
except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
Expand All @@ -1873,7 +1895,7 @@ def __init__(self, to, db_constraint=True, swappable=True, **kwargs):
db_constraint=db_constraint, db_constraint=db_constraint,
) )


self.swappable = swappable self._swappable = swappable
self.db_table = kwargs.pop('db_table', None) self.db_table = kwargs.pop('db_table', None)
if kwargs['rel'].through is not None: if kwargs['rel'].through is not None:
assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used." assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
Expand Down

0 comments on commit cc70dd0

Please sign in to comment.