Commit c049c43e authored by Simon Charette's avatar Simon Charette
Browse files

[1.9.x] Fixed #25723 -- Made related field checks lookup against their local apps.

Backport of c550beb0 from master
parent 84006fda
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ class RelatedField(Field):
        return []

    def _check_relation_model_exists(self):
        rel_is_missing = self.remote_field.model not in apps.get_models()
        rel_is_missing = self.remote_field.model not in self.opts.apps.get_models()
        rel_is_string = isinstance(self.remote_field.model, six.string_types)
        model_name = self.remote_field.model if rel_is_string else self.remote_field.model._meta.object_name
        if rel_is_missing and (rel_is_string or not self.remote_field.model._meta.swapped):
@@ -165,7 +165,7 @@ class RelatedField(Field):
        return []

    def _check_referencing_to_swapped_model(self):
        if (self.remote_field.model not in apps.get_models() and
        if (self.remote_field.model not in self.opts.apps.get_models() and
                not isinstance(self.remote_field.model, six.string_types) and
                self.remote_field.model._meta.swapped):
            model = "%s.%s" % (
@@ -1206,7 +1206,7 @@ class ManyToManyField(RelatedField):

        errors = []

        if self.remote_field.through not in apps.get_models(include_auto_created=True):
        if self.remote_field.through not in self.opts.apps.get_models(include_auto_created=True):
            # The relationship model is not installed.
            errors.append(
                checks.Error(
+68 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ from __future__ import unicode_literals

import warnings

from django.apps.registry import Apps
from django.core.checks import Error, Warning as DjangoWarning
from django.db import models
from django.db.models.fields.related import ForeignObject
@@ -132,6 +133,26 @@ class RelativeFieldTests(IsolatedModelsTestCase):
        ]
        self.assertEqual(errors, expected)

    def test_foreign_key_to_isolated_apps_model(self):
        """
        #25723 - Referenced model registration lookup should be run against the
        field's model registry.
        """
        test_apps = Apps(['invalid_models_tests'])

        class OtherModel(models.Model):
            class Meta:
                apps = test_apps

        class Model(models.Model):
            foreign_key = models.ForeignKey('OtherModel', models.CASCADE)

            class Meta:
                apps = test_apps

        field = Model._meta.get_field('foreign_key')
        self.assertEqual(field.check(from_model=Model), [])

    def test_many_to_many_to_missing_model(self):
        class Model(models.Model):
            m2m = models.ManyToManyField("Rel2")
@@ -149,6 +170,26 @@ class RelativeFieldTests(IsolatedModelsTestCase):
        ]
        self.assertEqual(errors, expected)

    def test_many_to_many_to_isolated_apps_model(self):
        """
        #25723 - Referenced model registration lookup should be run against the
        field's model registry.
        """
        test_apps = Apps(['invalid_models_tests'])

        class OtherModel(models.Model):
            class Meta:
                apps = test_apps

        class Model(models.Model):
            m2m = models.ManyToManyField('OtherModel')

            class Meta:
                apps = test_apps

        field = Model._meta.get_field('m2m')
        self.assertEqual(field.check(from_model=Model), [])

    def test_many_to_many_with_useless_options(self):
        class Model(models.Model):
            name = models.CharField(max_length=20)
@@ -288,6 +329,33 @@ class RelativeFieldTests(IsolatedModelsTestCase):
        ]
        self.assertEqual(errors, expected)

    def test_many_to_many_through_isolated_apps_model(self):
        """
        #25723 - Through model registration lookup should be run against the
        field's model registry.
        """
        test_apps = Apps(['invalid_models_tests'])

        class GroupMember(models.Model):
            person = models.ForeignKey('Person', models.CASCADE)
            group = models.ForeignKey('Group', models.CASCADE)

            class Meta:
                apps = test_apps

        class Person(models.Model):
            class Meta:
                apps = test_apps

        class Group(models.Model):
            members = models.ManyToManyField('Person', through='GroupMember')

            class Meta:
                apps = test_apps

        field = Group._meta.get_field('members')
        self.assertEqual(field.check(from_model=Group), [])

    def test_symmetrical_self_referential_field(self):
        class Person(models.Model):
            # Implicit symmetrical=False.