mirror of
https://github.com/django/django.git
synced 2025-08-30 23:37:50 +00:00
Fixed #29899 -- Made autodetector use model states instead of model classes.
Thanks Simon Charette and Markus Holtermann for reviews.
This commit is contained in:
parent
a67849499a
commit
aa4acc164d
3 changed files with 249 additions and 148 deletions
|
@ -584,9 +584,13 @@ class AutodetectorTests(TestCase):
|
|||
return project_state
|
||||
|
||||
def get_changes(self, before_states, after_states, questioner=None):
|
||||
if not isinstance(before_states, ProjectState):
|
||||
before_states = self.make_project_state(before_states)
|
||||
if not isinstance(after_states, ProjectState):
|
||||
after_states = self.make_project_state(after_states)
|
||||
return MigrationAutodetector(
|
||||
self.make_project_state(before_states),
|
||||
self.make_project_state(after_states),
|
||||
before_states,
|
||||
after_states,
|
||||
questioner,
|
||||
)._detect_changes()
|
||||
|
||||
|
@ -1646,30 +1650,38 @@ class AutodetectorTests(TestCase):
|
|||
"""
|
||||
# First, we test the default pk field name
|
||||
changes = self.get_changes([], [self.author_empty, self.author_proxy_third, self.book_proxy_fk])
|
||||
# The field name the FK on the book model points to
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'id')
|
||||
# The model the FK is pointing from and to.
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].fields[2][1].remote_field.model,
|
||||
'thirdapp.AuthorProxy',
|
||||
)
|
||||
# Now, we test the custom pk field name
|
||||
changes = self.get_changes([], [self.author_custom_pk, self.author_proxy_third, self.book_proxy_fk])
|
||||
# The field name the FK on the book model points to
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'pk_field')
|
||||
# The model the FK is pointing from and to.
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].fields[2][1].remote_field.model,
|
||||
'thirdapp.AuthorProxy',
|
||||
)
|
||||
|
||||
def test_proxy_to_mti_with_fk_to_proxy(self):
|
||||
# First, test the pk table and field name.
|
||||
changes = self.get_changes(
|
||||
[],
|
||||
to_state = self.make_project_state(
|
||||
[self.author_empty, self.author_proxy_third, self.book_proxy_fk],
|
||||
)
|
||||
changes = self.get_changes([], to_state)
|
||||
fk_field = changes['otherapp'][0].operations[0].fields[2][1]
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].fields[2][1].remote_field.model._meta.db_table,
|
||||
'testapp_author',
|
||||
to_state.get_concrete_model_key(fk_field.remote_field.model),
|
||||
('testapp', 'author'),
|
||||
)
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'id')
|
||||
self.assertEqual(fk_field.remote_field.model, 'thirdapp.AuthorProxy')
|
||||
|
||||
# Change AuthorProxy to use MTI.
|
||||
changes = self.get_changes(
|
||||
[self.author_empty, self.author_proxy_third, self.book_proxy_fk],
|
||||
from_state = to_state.clone()
|
||||
to_state = self.make_project_state(
|
||||
[self.author_empty, self.author_proxy_third_notproxy, self.book_proxy_fk],
|
||||
)
|
||||
changes = self.get_changes(from_state, to_state)
|
||||
# Right number/type of migrations for the AuthorProxy model?
|
||||
self.assertNumberMigrations(changes, 'thirdapp', 1)
|
||||
self.assertOperationTypes(changes, 'thirdapp', 0, ['DeleteModel', 'CreateModel'])
|
||||
|
@ -1680,30 +1692,39 @@ class AutodetectorTests(TestCase):
|
|||
# otherapp should depend on thirdapp.
|
||||
self.assertMigrationDependencies(changes, 'otherapp', 0, [('thirdapp', 'auto_1')])
|
||||
# Now, test the pk table and field name.
|
||||
fk_field = changes['otherapp'][0].operations[0].field
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].field.remote_field.model._meta.db_table,
|
||||
'thirdapp_authorproxy',
|
||||
to_state.get_concrete_model_key(fk_field.remote_field.model),
|
||||
('thirdapp', 'authorproxy'),
|
||||
)
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].field.remote_field.field_name, 'author_ptr')
|
||||
self.assertEqual(fk_field.remote_field.model, 'thirdapp.AuthorProxy')
|
||||
|
||||
def test_proxy_to_mti_with_fk_to_proxy_proxy(self):
|
||||
# First, test the pk table and field name.
|
||||
changes = self.get_changes(
|
||||
[],
|
||||
[self.author_empty, self.author_proxy, self.author_proxy_proxy, self.book_proxy_proxy_fk],
|
||||
)
|
||||
to_state = self.make_project_state([
|
||||
self.author_empty,
|
||||
self.author_proxy,
|
||||
self.author_proxy_proxy,
|
||||
self.book_proxy_proxy_fk,
|
||||
])
|
||||
changes = self.get_changes([], to_state)
|
||||
fk_field = changes['otherapp'][0].operations[0].fields[1][1]
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].fields[1][1].remote_field.model._meta.db_table,
|
||||
'testapp_author',
|
||||
to_state.get_concrete_model_key(fk_field.remote_field.model),
|
||||
('testapp', 'author'),
|
||||
)
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[1][1].remote_field.field_name, 'id')
|
||||
self.assertEqual(fk_field.remote_field.model, 'testapp.AAuthorProxyProxy')
|
||||
|
||||
# Change AuthorProxy to use MTI. FK still points to AAuthorProxyProxy,
|
||||
# a proxy of AuthorProxy.
|
||||
changes = self.get_changes(
|
||||
[self.author_empty, self.author_proxy, self.author_proxy_proxy, self.book_proxy_proxy_fk],
|
||||
[self.author_empty, self.author_proxy_notproxy, self.author_proxy_proxy, self.book_proxy_proxy_fk],
|
||||
)
|
||||
from_state = to_state.clone()
|
||||
to_state = self.make_project_state([
|
||||
self.author_empty,
|
||||
self.author_proxy_notproxy,
|
||||
self.author_proxy_proxy,
|
||||
self.book_proxy_proxy_fk,
|
||||
])
|
||||
changes = self.get_changes(from_state, to_state)
|
||||
# Right number/type of migrations for the AuthorProxy model?
|
||||
self.assertNumberMigrations(changes, 'testapp', 1)
|
||||
self.assertOperationTypes(changes, 'testapp', 0, ['DeleteModel', 'CreateModel'])
|
||||
|
@ -1714,11 +1735,12 @@ class AutodetectorTests(TestCase):
|
|||
# otherapp should depend on testapp.
|
||||
self.assertMigrationDependencies(changes, 'otherapp', 0, [('testapp', 'auto_1')])
|
||||
# Now, test the pk table and field name.
|
||||
fk_field = changes['otherapp'][0].operations[0].field
|
||||
self.assertEqual(
|
||||
changes['otherapp'][0].operations[0].field.remote_field.model._meta.db_table,
|
||||
'testapp_authorproxy',
|
||||
to_state.get_concrete_model_key(fk_field.remote_field.model),
|
||||
('testapp', 'authorproxy'),
|
||||
)
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].field.remote_field.field_name, 'author_ptr')
|
||||
self.assertEqual(fk_field.remote_field.model, 'testapp.AAuthorProxyProxy')
|
||||
|
||||
def test_unmanaged_create(self):
|
||||
"""The autodetector correctly deals with managed models."""
|
||||
|
@ -1761,12 +1783,14 @@ class AutodetectorTests(TestCase):
|
|||
"""
|
||||
# First, we test the default pk field name
|
||||
changes = self.get_changes([], [self.author_unmanaged_default_pk, self.book])
|
||||
# The field name the FK on the book model points to
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'id')
|
||||
# The model the FK on the book model points to.
|
||||
fk_field = changes['otherapp'][0].operations[0].fields[2][1]
|
||||
self.assertEqual(fk_field.remote_field.model, 'testapp.Author')
|
||||
# Now, we test the custom pk field name
|
||||
changes = self.get_changes([], [self.author_unmanaged_custom_pk, self.book])
|
||||
# The field name the FK on the book model points to
|
||||
self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'pk_field')
|
||||
# The model the FK on the book model points to.
|
||||
fk_field = changes['otherapp'][0].operations[0].fields[2][1]
|
||||
self.assertEqual(fk_field.remote_field.model, 'testapp.Author')
|
||||
|
||||
@override_settings(AUTH_USER_MODEL="thirdapp.CustomUser")
|
||||
def test_swappable(self):
|
||||
|
@ -1790,11 +1814,7 @@ class AutodetectorTests(TestCase):
|
|||
self.assertOperationTypes(changes, 'testapp', 0, ["AlterField"])
|
||||
self.assertOperationAttributes(changes, 'testapp', 0, 0, model_name="author", name='user')
|
||||
fk_field = changes['testapp'][0].operations[0].field
|
||||
to_model = '%s.%s' % (
|
||||
fk_field.remote_field.model._meta.app_label,
|
||||
fk_field.remote_field.model._meta.object_name,
|
||||
)
|
||||
self.assertEqual(to_model, 'thirdapp.CustomUser')
|
||||
self.assertEqual(fk_field.remote_field.model, 'thirdapp.CustomUser')
|
||||
|
||||
def test_add_field_with_default(self):
|
||||
"""#22030 - Adding a field with a default should work."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue