mirror of https://github.com/django/django.git
Fixed #26384 -- Fixed renaming the PK on a model with a self-referential FK on SQLite.
This commit is contained in:
parent
870dd1d38b
commit
4b2cf1cd27
|
@ -76,8 +76,16 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
3. copy the data from the old renamed table to the new table
|
3. copy the data from the old renamed table to the new table
|
||||||
4. delete the "app_model__old" table
|
4. delete the "app_model__old" table
|
||||||
"""
|
"""
|
||||||
|
# Self-referential fields must be recreated rather than copied from
|
||||||
|
# the old model to ensure their remote_field.field_name doesn't refer
|
||||||
|
# to an altered field.
|
||||||
|
def is_self_referential(f):
|
||||||
|
return f.is_relation and f.remote_field.model is model
|
||||||
# Work out the new fields dict / mapping
|
# Work out the new fields dict / mapping
|
||||||
body = {f.name: f for f in model._meta.local_concrete_fields}
|
body = {
|
||||||
|
f.name: f.clone() if is_self_referential(f) else f
|
||||||
|
for f in model._meta.local_concrete_fields
|
||||||
|
}
|
||||||
# Since mapping might mix column names and default values,
|
# Since mapping might mix column names and default values,
|
||||||
# its values must be already quoted.
|
# its values must be already quoted.
|
||||||
mapping = {f.column: self.quote_name(f.column) for f in model._meta.local_concrete_fields}
|
mapping = {f.column: self.quote_name(f.column) for f in model._meta.local_concrete_fields}
|
||||||
|
|
|
@ -43,3 +43,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a regression with abstract model inheritance and explicit parent links
|
* Fixed a regression with abstract model inheritance and explicit parent links
|
||||||
(:ticket:`26413`).
|
(:ticket:`26413`).
|
||||||
|
|
||||||
|
* Fixed a migrations crash on SQLite when renaming the primary key of a model
|
||||||
|
containing a ``ForeignKey`` to ``'self'`` (:ticket:`26384`).
|
||||||
|
|
|
@ -177,3 +177,8 @@ class UniqueTest(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
apps = new_apps
|
apps = new_apps
|
||||||
unique_together = ["year", "slug"]
|
unique_together = ["year", "slug"]
|
||||||
|
|
||||||
|
|
||||||
|
class Node(models.Model):
|
||||||
|
node_id = models.AutoField(primary_key=True)
|
||||||
|
parent = models.ForeignKey('self', models.CASCADE, null=True, blank=True)
|
||||||
|
|
|
@ -27,8 +27,8 @@ from .fields import (
|
||||||
from .models import (
|
from .models import (
|
||||||
Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book,
|
Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book,
|
||||||
BookForeignObj, BookWeak, BookWithLongName, BookWithO2O, BookWithoutAuthor,
|
BookForeignObj, BookWeak, BookWithLongName, BookWithO2O, BookWithoutAuthor,
|
||||||
BookWithSlug, IntegerPK, Note, NoteRename, Tag, TagIndexed, TagM2MTest,
|
BookWithSlug, IntegerPK, Node, Note, NoteRename, Tag, TagIndexed,
|
||||||
TagUniqueRename, Thing, UniqueTest, new_apps,
|
TagM2MTest, TagUniqueRename, Thing, UniqueTest, new_apps,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1819,3 +1819,14 @@ class SchemaTests(TransactionTestCase):
|
||||||
self.get_constraints_for_column(Tag, 'slug'),
|
self.get_constraints_for_column(Tag, 'slug'),
|
||||||
['schema_tag_slug_2c418ba3_like', 'schema_tag_slug_key']
|
['schema_tag_slug_2c418ba3_like', 'schema_tag_slug_key']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_alter_pk_with_self_referential_field(self):
|
||||||
|
"""
|
||||||
|
Changing the primary key field name of a model with a self-referential
|
||||||
|
foreign key (#26384).
|
||||||
|
"""
|
||||||
|
old_field = Node._meta.get_field('node_id')
|
||||||
|
new_field = AutoField(primary_key=True)
|
||||||
|
new_field.set_attributes_from_name('id')
|
||||||
|
with connection.schema_editor() as editor:
|
||||||
|
editor.alter_field(Node, old_field, new_field)
|
||||||
|
|
Loading…
Reference in New Issue