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

This commit is contained in:
Tim Graham 2015-07-15 14:38:10 -04:00
parent bbbb7ce115
commit c52822e750
3 changed files with 25 additions and 8 deletions

View File

@ -77,10 +77,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
4. delete the "app_model__old" table 4. delete the "app_model__old" table
""" """
# Work out the new fields dict / mapping # 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, # 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_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 # This maps field names (not columns) for things like unique_together
rename_mapping = {} rename_mapping = {}
# If any of the new or altered fields is introducing a new PK, # 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: for field in create_fields:
body[field.name] = field body[field.name] = field
# Choose a default and insert it into the copy map # 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( mapping[field.column] = self.quote_value(
self.effective_default(field) self.effective_default(field)
) )

View File

@ -89,6 +89,14 @@ class BookWithoutAuthor(models.Model):
db_table = "schema_book" 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): class IntegerPK(models.Model):
i = models.IntegerField(primary_key=True) i = models.IntegerField(primary_key=True)
j = models.IntegerField(unique=True) j = models.IntegerField(unique=True)

View File

@ -13,7 +13,7 @@ from django.db.models.fields import (
TextField, TimeField, TextField, TimeField,
) )
from django.db.models.fields.related import ( from django.db.models.fields.related import (
ForeignKey, ManyToManyField, OneToOneField, ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
) )
from django.db.transaction import atomic from django.db.transaction import atomic
from django.test import TransactionTestCase, skipIfDBFeature from django.test import TransactionTestCase, skipIfDBFeature
@ -22,10 +22,10 @@ from .fields import (
CustomManyToManyField, InheritedManyToManyField, MediumBlobField, CustomManyToManyField, InheritedManyToManyField, MediumBlobField,
) )
from .models import ( from .models import (
Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book, BookWeak, Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book,
BookWithLongName, BookWithO2O, BookWithoutAuthor, BookWithSlug, IntegerPK, BookForeignObj, BookWeak, BookWithLongName, BookWithO2O, BookWithoutAuthor,
Note, NoteRename, Tag, TagIndexed, TagM2MTest, TagUniqueRename, Thing, BookWithSlug, IntegerPK, Note, NoteRename, Tag, TagIndexed, TagM2MTest,
UniqueTest, new_apps, TagUniqueRename, Thing, UniqueTest, new_apps,
) )
@ -1507,6 +1507,15 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.add_field(BookWithLongName, new_field) 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): def test_creation_deletion_reserved_names(self):
""" """
Tries creating a model's table, and then deleting it when it has a Tries creating a model's table, and then deleting it when it has a