Commit c52822e7 authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #25128 -- Fixed SQLite SchemaEditor crash when adding a ForeignObject field.

parent bbbb7ce1
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -77,10 +77,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
          4. delete the "app_model__old" table
        """
        # Work out the new fields dict / mapping
        body = {f.name: f for f in model._meta.local_fields}
        body = {f.name: f for f in model._meta.local_concrete_fields}
        # Since mapping might mix column names and default values,
        # its values must be already quoted.
        mapping = {f.column: self.quote_name(f.column) for f in model._meta.local_fields}
        mapping = {f.column: self.quote_name(f.column) for f in model._meta.local_concrete_fields}
        # This maps field names (not columns) for things like unique_together
        rename_mapping = {}
        # If any of the new or altered fields is introducing a new PK,
@@ -98,7 +98,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
        for field in create_fields:
            body[field.name] = field
            # Choose a default and insert it into the copy map
            if not field.many_to_many:
            if not field.many_to_many and field.concrete:
                mapping[field.column] = self.quote_value(
                    self.effective_default(field)
                )
+8 −0
Original line number Diff line number Diff line
@@ -89,6 +89,14 @@ class BookWithoutAuthor(models.Model):
        db_table = "schema_book"


class BookForeignObj(models.Model):
    title = models.CharField(max_length=100, db_index=True)
    author_id = models.IntegerField()

    class Meta:
        apps = new_apps


class IntegerPK(models.Model):
    i = models.IntegerField(primary_key=True)
    j = models.IntegerField(unique=True)
+14 −5
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ from django.db.models.fields import (
    TextField, TimeField,
)
from django.db.models.fields.related import (
    ForeignKey, ManyToManyField, OneToOneField,
    ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
)
from django.db.transaction import atomic
from django.test import TransactionTestCase, skipIfDBFeature
@@ -22,10 +22,10 @@ from .fields import (
    CustomManyToManyField, InheritedManyToManyField, MediumBlobField,
)
from .models import (
    Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book, BookWeak,
    BookWithLongName, BookWithO2O, BookWithoutAuthor, BookWithSlug, IntegerPK,
    Note, NoteRename, Tag, TagIndexed, TagM2MTest, TagUniqueRename, Thing,
    UniqueTest, new_apps,
    Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book,
    BookForeignObj, BookWeak, BookWithLongName, BookWithO2O, BookWithoutAuthor,
    BookWithSlug, IntegerPK, Note, NoteRename, Tag, TagIndexed, TagM2MTest,
    TagUniqueRename, Thing, UniqueTest, new_apps,
)


@@ -1507,6 +1507,15 @@ class SchemaTests(TransactionTestCase):
        with connection.schema_editor() as editor:
            editor.add_field(BookWithLongName, new_field)

    def test_add_foreign_object(self):
        with connection.schema_editor() as editor:
            editor.create_model(BookForeignObj)

        new_field = ForeignObject(Author, from_fields=['author_id'], to_fields=['id'])
        new_field.set_attributes_from_name('author')
        with connection.schema_editor() as editor:
            editor.add_field(BookForeignObj, new_field)

    def test_creation_deletion_reserved_names(self):
        """
        Tries creating a model's table, and then deleting it when it has a