def test_real_apps(self): """ Tests that including real apps can resolve dangling FK errors. This test relies on the fact that contenttypes is always loaded. """ new_apps = Apps() class TestModel(models.Model): ct = models.ForeignKey("contenttypes.ContentType") class Meta: app_label = "migrations" apps = new_apps # If we just stick it into an empty state it should fail project_state = ProjectState() project_state.add_model_state(ModelState.from_model(TestModel)) with self.assertRaises(ValueError): project_state.render() # If we include the real app it should succeed project_state = ProjectState(real_apps=["contenttypes"]) project_state.add_model_state(ModelState.from_model(TestModel)) rendered_state = project_state.render() self.assertEqual( len([x for x in rendered_state.get_models() if x._meta.app_label == "migrations"]), 1, )
def test_real_apps(self): """ Tests that including real apps can resolve dangling FK errors. This test relies on the fact that contenttypes is always loaded. """ new_apps = Apps() class TestModel(models.Model): ct = models.ForeignKey("contenttypes.ContentType") class Meta: app_label = "migrations" apps = new_apps # If we just stick it into an empty state it should fail project_state = ProjectState() project_state.add_model_state(ModelState.from_model(TestModel)) with self.assertRaises(ValueError): project_state.render() # If we include the real app it should succeed project_state = ProjectState(real_apps=["contenttypes"]) project_state.add_model_state(ModelState.from_model(TestModel)) rendered_state = project_state.render() self.assertEqual( len([ x for x in rendered_state.get_models() if x._meta.app_label == "migrations" ]), 1, )
def test_dangling_references_throw_error(self): class Author(models.Model): name = models.TextField() class Book(models.Model): author = models.ForeignKey(Author) class Magazine(models.Model): authors = models.ManyToManyField(Author) # Make a valid ProjectState and render it project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Author)) project_state.add_model_state(ModelState.from_model(Book)) project_state.add_model_state(ModelState.from_model(Magazine)) rendered_state = project_state.render() self.assertEqual(len(rendered_state.get_models()), 3) # now make an invalid one with a ForeignKey project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Book)) with self.assertRaises(ValueError): rendered_state = project_state.render() # and another with ManyToManyField project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Magazine)) with self.assertRaises(ValueError): rendered_state = project_state.render()
def test_render_project_dependencies(self): """ Tests that the ProjectState render method correctly renders models to account for inter-model base dependencies. """ new_apps = Apps() class A(models.Model): class Meta: app_label = "migrations" apps = new_apps class B(A): class Meta: app_label = "migrations" apps = new_apps class C(B): class Meta: app_label = "migrations" apps = new_apps class D(A): class Meta: app_label = "migrations" apps = new_apps class E(B): class Meta: app_label = "migrations" apps = new_apps proxy = True class F(D): class Meta: app_label = "migrations" apps = new_apps proxy = True # Make a ProjectState and render it project_state = ProjectState() project_state.add_model_state(ModelState.from_model(A)) project_state.add_model_state(ModelState.from_model(B)) project_state.add_model_state(ModelState.from_model(C)) project_state.add_model_state(ModelState.from_model(D)) project_state.add_model_state(ModelState.from_model(E)) project_state.add_model_state(ModelState.from_model(F)) final_apps = project_state.render() self.assertEqual(len(final_apps.get_models()), 6) # Now make an invalid ProjectState and make sure it fails project_state = ProjectState() project_state.add_model_state(ModelState.from_model(A)) project_state.add_model_state(ModelState.from_model(B)) project_state.add_model_state(ModelState.from_model(C)) project_state.add_model_state(ModelState.from_model(F)) with self.assertRaises(InvalidBasesError): project_state.render()
def test_render_project_dependencies(self): """ Tests that the ProjectState render method correctly renders models to account for inter-model base dependencies. """ new_app_cache = AppCache() class A(models.Model): class Meta: app_label = "migrations" app_cache = new_app_cache class B(A): class Meta: app_label = "migrations" app_cache = new_app_cache class C(B): class Meta: app_label = "migrations" app_cache = new_app_cache class D(A): class Meta: app_label = "migrations" app_cache = new_app_cache class E(B): class Meta: app_label = "migrations" app_cache = new_app_cache proxy = True class F(D): class Meta: app_label = "migrations" app_cache = new_app_cache proxy = True # Make a ProjectState and render it project_state = ProjectState() project_state.add_model_state(ModelState.from_model(A)) project_state.add_model_state(ModelState.from_model(B)) project_state.add_model_state(ModelState.from_model(C)) project_state.add_model_state(ModelState.from_model(D)) project_state.add_model_state(ModelState.from_model(E)) project_state.add_model_state(ModelState.from_model(F)) final_app_cache = project_state.render() self.assertEqual(len(final_app_cache.get_models()), 6) # Now make an invalid ProjectState and make sure it fails project_state = ProjectState() project_state.add_model_state(ModelState.from_model(A)) project_state.add_model_state(ModelState.from_model(B)) project_state.add_model_state(ModelState.from_model(C)) project_state.add_model_state(ModelState.from_model(F)) with self.assertRaises(InvalidBasesError): project_state.render()
def test_repr(self): field = models.CharField(max_length=1) state = ModelState('app', 'Model', [('name', field)], bases=['app.A', 'app.B', 'app.C']) self.assertEqual(repr(state), "<ModelState: 'app.Model'>") project_state = ProjectState() project_state.add_model_state(state) with self.assertRaisesMessage(InvalidBasesError, "Cannot resolve bases for [<ModelState: 'app.Model'>]"): project_state.render()
def test_render(self): """ Tests rendering a ProjectState into an AppCache. """ project_state = ProjectState() project_state.add_model_state( ModelState( "migrations", "Tag", [ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], {}, None, )) new_app_cache = project_state.render() self.assertEqual( new_app_cache.get_model( "migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual( new_app_cache.get_model( "migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False)
def test_render(self): """ Tests rendering a ProjectState into an Apps. """ project_state = ProjectState() project_state.add_model_state(ModelState( app_label="migrations", name="Tag", fields=[ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], )) project_state.add_model_state(ModelState( app_label="migrations", name="SubTag", fields=[ ('tag_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='migrations.Tag', )), ("awesome", models.BooleanField()), ], bases=("migrations.Tag",), )) base_mgr = models.Manager() mgr1 = FoodManager('a', 'b') mgr2 = FoodManager('x', 'y', c=3, d=4) project_state.add_model_state(ModelState( app_label="migrations", name="Food", fields=[ ("id", models.AutoField(primary_key=True)), ], managers=[ # The ordering we really want is objects, mgr1, mgr2 ('default', base_mgr), ('food_mgr2', mgr2), ('food_mgr1', mgr1), ] )) new_apps = project_state.render() self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) self.assertEqual(len(new_apps.get_model("migrations", "SubTag")._meta.local_fields), 2) Food = new_apps.get_model("migrations", "Food") managers = sorted(Food._meta.managers) self.assertEqual([mgr.name for _, mgr, _ in managers], ['default', 'food_mgr1', 'food_mgr2']) self.assertEqual([mgr.__class__ for _, mgr, _ in managers], [models.Manager, FoodManager, FoodManager]) self.assertIs(managers[0][1], Food._default_manager)
def test_dangling_references_throw_error(self): new_apps = Apps() class Author(models.Model): name = models.TextField() class Meta: app_label = "migrations" apps = new_apps class Book(models.Model): author = models.ForeignKey(Author) class Meta: app_label = "migrations" apps = new_apps class Magazine(models.Model): authors = models.ManyToManyField(Author) class Meta: app_label = "migrations" apps = new_apps # Make a valid ProjectState and render it project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Author)) project_state.add_model_state(ModelState.from_model(Book)) project_state.add_model_state(ModelState.from_model(Magazine)) rendered_state = project_state.render() self.assertEqual(len(rendered_state.get_models()), 3) # now make an invalid one with a ForeignKey project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Book)) with self.assertRaises(ValueError): rendered_state = project_state.render() # and another with ManyToManyField project_state = ProjectState() project_state.add_model_state(ModelState.from_model(Magazine)) with self.assertRaises(ValueError): rendered_state = project_state.render()
def test_render(self): """ Tests rendering a ProjectState into an Apps. """ project_state = ProjectState() project_state.add_model_state( ModelState( "migrations", "Tag", [ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], {}, None, )) project_state.add_model_state( ModelState( "migrations", "SubTag", [ ('tag_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='migrations.Tag', )), ("awesome", models.BooleanField()), ], options={}, bases=("migrations.Tag", ), )) new_apps = project_state.render() self.assertEqual( new_apps.get_model( "migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual( new_apps.get_model( "migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) self.assertEqual( len(new_apps.get_model("migrations", "SubTag")._meta.local_fields), 2)
def test_render_unique_app_labels(self): """ Tests that the ProjectState render method doesn't raise an ImproperlyConfigured exception about unique labels if two dotted app names have the same last part. """ class A(models.Model): class Meta: app_label = "django.contrib.auth" class B(models.Model): class Meta: app_label = "vendor.auth" # Make a ProjectState and render it project_state = ProjectState() project_state.add_model_state(ModelState.from_model(A)) project_state.add_model_state(ModelState.from_model(B)) final_apps = project_state.render() self.assertEqual(len(final_apps.get_models()), 2)
def test_render(self): """ Tests rendering a ProjectState into an AppCache. """ project_state = ProjectState() project_state.add_model_state(ModelState( "migrations", "Tag", [ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], {}, None, )) new_app_cache = project_state.render() self.assertEqual(new_app_cache.get_model("migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual(new_app_cache.get_model("migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False)
def test_render(self): """ Tests rendering a ProjectState into an Apps. """ project_state = ProjectState() project_state.add_model_state(ModelState( "migrations", "Tag", [ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], {}, None, )) project_state.add_model_state(ModelState( "migrations", "SubTag", [ ('tag_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='migrations.Tag', )), ("awesome", models.BooleanField()), ], options={}, bases=("migrations.Tag",), )) new_apps = project_state.render() self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) self.assertEqual(len(new_apps.get_model("migrations", "SubTag")._meta.local_fields), 2)
def test_render(self): """ Tests rendering a ProjectState into an Apps. """ project_state = ProjectState() project_state.add_model_state( ModelState( app_label="migrations", name="Tag", fields=[ ("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100)), ("hidden", models.BooleanField()), ], )) project_state.add_model_state( ModelState( app_label="migrations", name="SubTag", fields=[ ('tag_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='migrations.Tag', )), ("awesome", models.BooleanField()), ], bases=("migrations.Tag", ), )) base_mgr = models.Manager() mgr1 = FoodManager('a', 'b') mgr2 = FoodManager('x', 'y', c=3, d=4) project_state.add_model_state( ModelState( app_label="migrations", name="Food", fields=[ ("id", models.AutoField(primary_key=True)), ], managers=[ # The ordering we really want is objects, mgr1, mgr2 ('default', base_mgr), ('food_mgr2', mgr2), ('food_mgr1', mgr1), ])) new_apps = project_state.render() self.assertEqual( new_apps.get_model( "migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) self.assertEqual( new_apps.get_model( "migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) self.assertEqual( len(new_apps.get_model("migrations", "SubTag")._meta.local_fields), 2) Food = new_apps.get_model("migrations", "Food") managers = sorted(Food._meta.managers) self.assertEqual([mgr.name for _, mgr, _ in managers], ['default', 'food_mgr1', 'food_mgr2']) self.assertEqual([mgr.__class__ for _, mgr, _ in managers], [models.Manager, FoodManager, FoodManager]) self.assertIs(managers[0][1], Food._default_manager)