Python django.db.models.deletion.CASCADE Examples

The following are 30 code examples of django.db.models.deletion.CASCADE(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.db.models.deletion , or try the search function .
Example #1
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def _test_m2m_create(self, M2MFieldClass):
        """
        Tests M2M fields on models during creation
        """
        class LocalBookWithM2M(Model):
            author = ForeignKey(Author, CASCADE)
            title = CharField(max_length=100, db_index=True)
            pub_date = DateTimeField()
            tags = M2MFieldClass("TagM2MTest", related_name="books")

            class Meta:
                app_label = 'schema'
                apps = new_apps
        self.local_models = [LocalBookWithM2M]
        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(TagM2MTest)
            editor.create_model(LocalBookWithM2M)
        # Ensure there is now an m2m table there
        columns = self.column_classes(LocalBookWithM2M._meta.get_field("tags").remote_field.through)
        self.assertEqual(columns['tagm2mtest_id'][0], "IntegerField") 
Example #2
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_alter_fk(self):
        """
        Tests altering of FKs
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        # Ensure the field is right to begin with
        columns = self.column_classes(Book)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
        # Alter the FK
        old_field = Book._meta.get_field("author")
        new_field = ForeignKey(Author, CASCADE, editable=False)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)
        # Ensure the field is right afterwards
        columns = self.column_classes(Book)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author') 
Example #3
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_alter_fk(self):
        """
        Tests altering of FKs
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        # Ensure the field is right to begin with
        columns = self.column_classes(Book)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
        # Alter the FK
        old_field = Book._meta.get_field("author")
        new_field = ForeignKey(Author, CASCADE, editable=False)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)
        # Ensure the field is right afterwards
        columns = self.column_classes(Book)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author') 
Example #4
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_fk_to_proxy(self):
        "Creating a FK to a proxy model creates database constraints."
        class AuthorProxy(Author):
            class Meta:
                app_label = 'schema'
                apps = new_apps
                proxy = True

        class AuthorRef(Model):
            author = ForeignKey(AuthorProxy, on_delete=CASCADE)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [AuthorProxy, AuthorRef]

        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(AuthorRef)
        self.assertForeignKeyExists(AuthorRef, 'author_id', 'schema_author') 
Example #5
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_fk(self):
        "Creating tables out of FK order, then repointing, works"
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Book)
            editor.create_model(Author)
            editor.create_model(Tag)
        # Initial tables are there
        list(Author.objects.all())
        list(Book.objects.all())
        # Make sure the FK constraint is present
        with self.assertRaises(IntegrityError):
            Book.objects.create(
                author_id=1,
                title="Much Ado About Foreign Keys",
                pub_date=datetime.datetime.now(),
            )
        # Repoint the FK constraint
        old_field = Book._meta.get_field("author")
        new_field = ForeignKey(Tag, CASCADE)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)
        self.assertForeignKeyExists(Book, 'author_id', 'schema_tag') 
Example #6
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_fk_to_proxy(self):
        "Creating a FK to a proxy model creates database constraints."
        class AuthorProxy(Author):
            class Meta:
                app_label = 'schema'
                apps = new_apps
                proxy = True

        class AuthorRef(Model):
            author = ForeignKey(AuthorProxy, on_delete=CASCADE)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [AuthorProxy, AuthorRef]

        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(AuthorRef)
        self.assertForeignKeyExists(AuthorRef, 'author_id', 'schema_author') 
Example #7
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_rename_referenced_field(self):
        class Author(Model):
            name = CharField(max_length=255, unique=True)

            class Meta:
                app_label = 'schema'

        class Book(Model):
            author = ForeignKey(Author, CASCADE, to_field='name')

            class Meta:
                app_label = 'schema'

        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        new_field = CharField(max_length=255, unique=True)
        new_field.set_attributes_from_name('renamed')
        with connection.schema_editor(atomic=connection.features.supports_atomic_references_rename) as editor:
            editor.alter_field(Author, Author._meta.get_field('name'), new_field)
        # Ensure the foreign key reference was updated.
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author', 'renamed') 
Example #8
Source File: related.py    From luscan-devel with GNU General Public License v2.0 6 votes vote down vote up
def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
        try:
            to_name = to._meta.object_name.lower()
        except AttributeError:  # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
            assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
        else:
            assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
            # For backwards compatibility purposes, we need to *try* and set
            # the to_field during FK construction. It won't be guaranteed to
            # be correct until contribute_to_class is called. Refs #12190.
            to_field = to_field or (to._meta.pk and to._meta.pk.name)
        kwargs['verbose_name'] = kwargs.get('verbose_name', None)

        if 'db_index' not in kwargs:
            kwargs['db_index'] = True

        kwargs['rel'] = rel_class(to, to_field,
            related_name=kwargs.pop('related_name', None),
            limit_choices_to=kwargs.pop('limit_choices_to', None),
            parent_link=kwargs.pop('parent_link', False),
            on_delete=kwargs.pop('on_delete', CASCADE),
        )
        Field.__init__(self, **kwargs) 
Example #9
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_unique_together_with_fk_with_existing_index(self):
        """
        Tests removing and adding unique_together constraints that include
        a foreign key, where the foreign key is added after the model is
        created.
        """
        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithoutAuthor)
            new_field = ForeignKey(Author, CASCADE)
            new_field.set_attributes_from_name('author')
            editor.add_field(BookWithoutAuthor, new_field)
        # Ensure the fields aren't unique to begin with
        self.assertEqual(Book._meta.unique_together, ())
        # Add the unique_together constraint
        with connection.schema_editor() as editor:
            editor.alter_unique_together(Book, [], [['author', 'title']])
        # Alter it back
        with connection.schema_editor() as editor:
            editor.alter_unique_together(Book, [['author', 'title']], []) 
Example #10
Source File: related.py    From GTDWeb with GNU General Public License v2.0 6 votes vote down vote up
def __init__(self, to, from_fields, to_fields, swappable=True, **kwargs):
        self.from_fields = from_fields
        self.to_fields = to_fields
        self.swappable = swappable

        if 'rel' not in kwargs:
            kwargs['rel'] = ForeignObjectRel(
                self, to,
                related_name=kwargs.pop('related_name', None),
                related_query_name=kwargs.pop('related_query_name', None),
                limit_choices_to=kwargs.pop('limit_choices_to', None),
                parent_link=kwargs.pop('parent_link', False),
                on_delete=kwargs.pop('on_delete', CASCADE),
            )
        kwargs['verbose_name'] = kwargs.get('verbose_name', None)

        super(ForeignObject, self).__init__(**kwargs) 
Example #11
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_add_foreign_key_quoted_db_table(self):
        class Author(Model):
            class Meta:
                db_table = '"table_author_double_quoted"'
                app_label = 'schema'

        class Book(Model):
            author = ForeignKey(Author, CASCADE)

            class Meta:
                app_label = 'schema'

        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        if connection.vendor == 'mysql':
            self.assertForeignKeyExists(Book, 'author_id', '"table_author_double_quoted"')
        else:
            self.assertForeignKeyExists(Book, 'author_id', 'table_author_double_quoted') 
Example #12
Source File: tests.py    From django-sqlserver with MIT License 6 votes vote down vote up
def test_unique_together_with_fk_with_existing_index(self):
        """
        Tests removing and adding unique_together constraints that include
        a foreign key, where the foreign key is added after the model is
        created.
        """
        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithoutAuthor)
            new_field = ForeignKey(Author, CASCADE)
            new_field.set_attributes_from_name('author')
            editor.add_field(BookWithoutAuthor, new_field)
        # Ensure the fields aren't unique to begin with
        self.assertEqual(Book._meta.unique_together, ())
        # Add the unique_together constraint
        with connection.schema_editor() as editor:
            editor.alter_unique_together(Book, [], [['author', 'title']])
        # Alter it back
        with connection.schema_editor() as editor:
            editor.alter_unique_together(Book, [['author', 'title']], []) 
Example #13
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_rename_column_renames_deferred_sql_references(self):
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
            old_title = Book._meta.get_field('title')
            new_title = CharField(max_length=100, db_index=True)
            new_title.set_attributes_from_name('renamed_title')
            editor.alter_field(Book, old_title, new_title)
            old_author = Book._meta.get_field('author')
            new_author = ForeignKey(Author, CASCADE)
            new_author.set_attributes_from_name('renamed_author')
            editor.alter_field(Book, old_author, new_author)
            self.assertGreater(len(editor.deferred_sql), 0)
            for statement in editor.deferred_sql:
                self.assertIs(statement.references_column('book', 'title'), False)
                self.assertIs(statement.references_column('book', 'author_id'), False) 
Example #14
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_fk(self):
        "Creating tables out of FK order, then repointing, works"
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Book)
            editor.create_model(Author)
            editor.create_model(Tag)
        # Initial tables are there
        list(Author.objects.all())
        list(Book.objects.all())
        # Make sure the FK constraint is present
        with self.assertRaises(IntegrityError):
            Book.objects.create(
                author_id=1,
                title="Much Ado About Foreign Keys",
                pub_date=datetime.datetime.now(),
            )
        # Repoint the FK constraint
        old_field = Book._meta.get_field("author")
        new_field = ForeignKey(Tag, CASCADE)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)
        self.assertForeignKeyExists(Book, 'author_id', 'schema_tag') 
Example #15
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_char_field_with_db_index_to_fk(self):
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(AuthorCharFieldWithIndex)
        # Change CharField to FK
        old_field = AuthorCharFieldWithIndex._meta.get_field('char_field')
        new_field = ForeignKey(Author, CASCADE, blank=True)
        new_field.set_attributes_from_name('char_field')
        with connection.schema_editor() as editor:
            editor.alter_field(AuthorCharFieldWithIndex, old_field, new_field, strict=True)
        self.assertForeignKeyExists(AuthorCharFieldWithIndex, 'char_field_id', 'schema_author') 
Example #16
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_no_index_for_foreignkey(self):
        """
        MySQL on InnoDB already creates indexes automatically for foreign keys.
        (#14180). An index should be created if db_constraint=False (#26171).
        """
        storage = connection.introspection.get_storage_engine(
            connection.cursor(), ArticleTranslation._meta.db_table
        )
        if storage != "InnoDB":
            self.skip("This test only applies to the InnoDB storage engine")
        index_sql = [str(statement) for statement in connection.schema_editor()._model_indexes_sql(ArticleTranslation)]
        self.assertEqual(index_sql, [
            'CREATE INDEX `indexes_articletranslation_article_no_constraint_id_d6c0806b` '
            'ON `indexes_articletranslation` (`article_no_constraint_id`)'
        ])

        # The index also shouldn't be created if the ForeignKey is added after
        # the model was created.
        field_created = False
        try:
            with connection.schema_editor() as editor:
                new_field = ForeignKey(Article, CASCADE)
                new_field.set_attributes_from_name('new_foreign_key')
                editor.add_field(ArticleTranslation, new_field)
                field_created = True
                self.assertEqual([str(statement) for statement in editor.deferred_sql], [
                    'ALTER TABLE `indexes_articletranslation` '
                    'ADD CONSTRAINT `indexes_articletrans_new_foreign_key_id_d27a9146_fk_indexes_a` '
                    'FOREIGN KEY (`new_foreign_key_id`) REFERENCES `indexes_article` (`id`)'
                ])
        finally:
            if field_created:
                with connection.schema_editor() as editor:
                    editor.remove_field(ArticleTranslation, new_field) 
Example #17
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_text_field_with_db_index_to_fk(self):
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(AuthorTextFieldWithIndex)
        # Change TextField to FK
        old_field = AuthorTextFieldWithIndex._meta.get_field('text_field')
        new_field = ForeignKey(Author, CASCADE, blank=True)
        new_field.set_attributes_from_name('text_field')
        with connection.schema_editor() as editor:
            editor.alter_field(AuthorTextFieldWithIndex, old_field, new_field, strict=True)
        self.assertForeignKeyExists(AuthorTextFieldWithIndex, 'text_field_id', 'schema_author') 
Example #18
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_no_db_constraint_added_during_primary_key_change(self):
        """
        When a primary key that's pointed to by a ForeignKey with
        db_constraint=False is altered, a foreign key constraint isn't added.
        """
        class Author(Model):
            class Meta:
                app_label = 'schema'

        class BookWeak(Model):
            author = ForeignKey(Author, CASCADE, db_constraint=False)

            class Meta:
                app_label = 'schema'

        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWeak)
        self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
        old_field = Author._meta.get_field('id')
        new_field = BigAutoField(primary_key=True)
        new_field.model = Author
        new_field.set_attributes_from_name('id')
        # @isolate_apps() and inner models are needed to have the model
        # relations populated, otherwise this doesn't act as a regression test.
        self.assertEqual(len(new_field.model._meta.related_objects), 1)
        with connection.schema_editor() as editor:
            editor.alter_field(Author, old_field, new_field, strict=True)
        self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author') 
Example #19
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_fk_checks_deferred_constraints(self):
        """
        #25492 - Altering a foreign key's structure and data in the same
        transaction.
        """
        with connection.schema_editor() as editor:
            editor.create_model(Node)
        old_field = Node._meta.get_field('parent')
        new_field = ForeignKey(Node, CASCADE)
        new_field.set_attributes_from_name('parent')
        parent = Node.objects.create()
        with connection.schema_editor() as editor:
            # Update the parent FK to create a deferred constraint check.
            Node.objects.update(parent=parent)
            editor.alter_field(Node, old_field, new_field, strict=True) 
Example #20
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_to_fk(self):
        """
        #24447 - Tests adding a FK constraint for an existing column
        """
        class LocalBook(Model):
            author = IntegerField()
            title = CharField(max_length=100, db_index=True)
            pub_date = DateTimeField()

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [LocalBook]

        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(LocalBook)
        # Ensure no FK constraint exists
        constraints = self.get_constraints(LocalBook._meta.db_table)
        for details in constraints.values():
            if details['foreign_key']:
                self.fail('Found an unexpected FK constraint to %s' % details['columns'])
        old_field = LocalBook._meta.get_field("author")
        new_field = ForeignKey(Author, CASCADE)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(LocalBook, old_field, new_field, strict=True)
        self.assertForeignKeyExists(LocalBook, 'author_id', 'schema_author') 
Example #21
Source File: tests.py    From django-sqlserver with MIT License 5 votes vote down vote up
def _test_m2m_through_alter(self, M2MFieldClass):
        """
        Tests altering M2Ms with explicit through models (should no-op)
        """
        class LocalAuthorTag(Model):
            author = ForeignKey("schema.LocalAuthorWithM2MThrough", CASCADE)
            tag = ForeignKey("schema.TagM2MTest", CASCADE)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        class LocalAuthorWithM2MThrough(Model):
            name = CharField(max_length=255)
            tags = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [LocalAuthorTag, LocalAuthorWithM2MThrough]

        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(LocalAuthorTag)
            editor.create_model(LocalAuthorWithM2MThrough)
            editor.create_model(TagM2MTest)
        # Ensure the m2m table is there
        self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3)
        # "Alter" the field's blankness. This should not actually do anything.
        old_field = LocalAuthorWithM2MThrough._meta.get_field("tags")
        new_field = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)
        new_field.contribute_to_class(LocalAuthorWithM2MThrough, "tags")
        with connection.schema_editor() as editor:
            editor.alter_field(LocalAuthorWithM2MThrough, old_field, new_field, strict=True)
        # Ensure the m2m table is still there
        self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3) 
Example #22
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_o2o_to_fk(self):
        """
        #24163 - Tests altering of OneToOneField to ForeignKey
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithO2O)
        # Ensure the field is right to begin with
        columns = self.column_classes(BookWithO2O)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        # Ensure the field is unique
        author = Author.objects.create(name="Joe")
        BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
        with self.assertRaises(IntegrityError):
            BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
        BookWithO2O.objects.all().delete()
        self.assertForeignKeyExists(BookWithO2O, 'author_id', 'schema_author')
        # Alter the OneToOneField to ForeignKey
        old_field = BookWithO2O._meta.get_field("author")
        new_field = ForeignKey(Author, CASCADE)
        new_field.set_attributes_from_name("author")
        with connection.schema_editor() as editor:
            editor.alter_field(BookWithO2O, old_field, new_field, strict=True)
        # Ensure the field is right afterwards
        columns = self.column_classes(Book)
        self.assertEqual(columns['author_id'][0], "IntegerField")
        # Ensure the field is not unique anymore
        Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
        Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
        self.assertForeignKeyExists(Book, 'author_id', 'schema_author') 
Example #23
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_field_fk_to_o2o(self):
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        expected_fks = 1 if connection.features.supports_foreign_keys else 0

        # Check the index is right to begin with.
        counts = self.get_constraints_count(
            Book._meta.db_table,
            Book._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 0, 'indexes': 1})

        old_field = Book._meta.get_field('author')
        new_field = OneToOneField(Author, CASCADE)
        new_field.set_attributes_from_name('author')
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)

        counts = self.get_constraints_count(
            Book._meta.db_table,
            Book._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        # The index on ForeignKey is replaced with a unique constraint for OneToOneField.
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0}) 
Example #24
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_field_fk_keeps_index(self):
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        expected_fks = 1 if connection.features.supports_foreign_keys else 0

        # Check the index is right to begin with.
        counts = self.get_constraints_count(
            Book._meta.db_table,
            Book._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 0, 'indexes': 1})

        old_field = Book._meta.get_field('author')
        # on_delete changed from CASCADE.
        new_field = ForeignKey(Author, PROTECT)
        new_field.set_attributes_from_name('author')
        with connection.schema_editor() as editor:
            editor.alter_field(Book, old_field, new_field, strict=True)

        counts = self.get_constraints_count(
            Book._meta.db_table,
            Book._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        # The index remains.
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 0, 'indexes': 1}) 
Example #25
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_field_o2o_to_fk(self):
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithO2O)
        expected_fks = 1 if connection.features.supports_foreign_keys else 0

        # Check the unique constraint is right to begin with.
        counts = self.get_constraints_count(
            BookWithO2O._meta.db_table,
            BookWithO2O._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})

        old_field = BookWithO2O._meta.get_field('author')
        new_field = ForeignKey(Author, CASCADE)
        new_field.set_attributes_from_name('author')
        with connection.schema_editor() as editor:
            editor.alter_field(BookWithO2O, old_field, new_field, strict=True)

        counts = self.get_constraints_count(
            BookWithO2O._meta.db_table,
            BookWithO2O._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        # The unique constraint on OneToOneField is replaced with an index for ForeignKey.
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 0, 'indexes': 1}) 
Example #26
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_alter_field_o2o_keeps_unique(self):
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithO2O)
        expected_fks = 1 if connection.features.supports_foreign_keys else 0

        # Check the unique constraint is right to begin with.
        counts = self.get_constraints_count(
            BookWithO2O._meta.db_table,
            BookWithO2O._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})

        old_field = BookWithO2O._meta.get_field('author')
        # on_delete changed from CASCADE.
        new_field = OneToOneField(Author, PROTECT)
        new_field.set_attributes_from_name('author')
        with connection.schema_editor() as editor:
            editor.alter_field(BookWithO2O, old_field, new_field, strict=True)

        counts = self.get_constraints_count(
            BookWithO2O._meta.db_table,
            BookWithO2O._meta.get_field('author').column,
            (Author._meta.db_table, Author._meta.pk.column),
        )
        # The unique constraint remains.
        self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0}) 
Example #27
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def _test_m2m_create_through(self, M2MFieldClass):
        """
        Tests M2M fields on models during creation with through models
        """
        class LocalTagThrough(Model):
            book = ForeignKey("schema.LocalBookWithM2MThrough", CASCADE)
            tag = ForeignKey("schema.TagM2MTest", CASCADE)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        class LocalBookWithM2MThrough(Model):
            tags = M2MFieldClass("TagM2MTest", related_name="books", through=LocalTagThrough)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [LocalTagThrough, LocalBookWithM2MThrough]

        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(LocalTagThrough)
            editor.create_model(TagM2MTest)
            editor.create_model(LocalBookWithM2MThrough)
        # Ensure there is now an m2m table there
        columns = self.column_classes(LocalTagThrough)
        self.assertEqual(columns['book_id'][0], "IntegerField")
        self.assertEqual(columns['tag_id'][0], "IntegerField") 
Example #28
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def _test_m2m_through_alter(self, M2MFieldClass):
        """
        Tests altering M2Ms with explicit through models (should no-op)
        """
        class LocalAuthorTag(Model):
            author = ForeignKey("schema.LocalAuthorWithM2MThrough", CASCADE)
            tag = ForeignKey("schema.TagM2MTest", CASCADE)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        class LocalAuthorWithM2MThrough(Model):
            name = CharField(max_length=255)
            tags = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)

            class Meta:
                app_label = 'schema'
                apps = new_apps

        self.local_models = [LocalAuthorTag, LocalAuthorWithM2MThrough]

        # Create the tables
        with connection.schema_editor() as editor:
            editor.create_model(LocalAuthorTag)
            editor.create_model(LocalAuthorWithM2MThrough)
            editor.create_model(TagM2MTest)
        # Ensure the m2m table is there
        self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3)
        # "Alter" the field's blankness. This should not actually do anything.
        old_field = LocalAuthorWithM2MThrough._meta.get_field("tags")
        new_field = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)
        new_field.contribute_to_class(LocalAuthorWithM2MThrough, "tags")
        with connection.schema_editor() as editor:
            editor.alter_field(LocalAuthorWithM2MThrough, old_field, new_field, strict=True)
        # Ensure the m2m table is still there
        self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3) 
Example #29
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_unique_no_unnecessary_fk_drops(self):
        """
        If AlterField isn't selective about dropping foreign key constraints
        when modifying a field with a unique constraint, the AlterField
        incorrectly drops and recreates the Book.author foreign key even though
        it doesn't restrict the field being changed (#29193).
        """
        class Author(Model):
            name = CharField(max_length=254, unique=True)

            class Meta:
                app_label = 'schema'

        class Book(Model):
            author = ForeignKey(Author, CASCADE)

            class Meta:
                app_label = 'schema'

        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(Book)
        new_field = CharField(max_length=255, unique=True)
        new_field.model = Author
        new_field.set_attributes_from_name('name')
        with self.assertLogs('django.db.backends.schema', 'DEBUG') as cm:
            with connection.schema_editor() as editor:
                editor.alter_field(Author, Author._meta.get_field('name'), new_field)
        # One SQL statement is executed to alter the field.
        self.assertEqual(len(cm.records), 1) 
Example #30
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_add_foreign_key_long_names(self):
        """
        Regression test for #23009.
        Only affects databases that supports foreign keys.
        """
        # Create the initial tables
        with connection.schema_editor() as editor:
            editor.create_model(AuthorWithEvenLongerName)
            editor.create_model(BookWithLongName)
        # Add a second FK, this would fail due to long ref name before the fix
        new_field = ForeignKey(AuthorWithEvenLongerName, CASCADE, related_name="something")
        new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk")
        with connection.schema_editor() as editor:
            editor.add_field(BookWithLongName, new_field)