Beispiel #1
0
 def test_unavailable_site_model(self):
     """
     #24075 - A Site shouldn't be created if the model isn't available.
     """
     apps = Apps()
     create_default_site(self.app_config, verbosity=0, apps=apps)
     self.assertFalse(Site.objects.exists())
Beispiel #2
0
 def test_ready(self):
     """
     Tests the ready property of the master registry.
     """
     # The master app registry is always ready when the tests run.
     self.assertIs(apps.ready, True)
     # Non-master app registries are populated in __init__.
     self.assertIs(Apps().ready, True)
Beispiel #3
0
            class M(models.Model):
                foo = models.IntegerField()
                bar = models.IntegerField()
                baz = models.IntegerField()

                Meta = type('Meta', (), {
                    'unique_together': unique_together,
                    'apps': Apps()
                })
Beispiel #4
0
 def test_register_model_class_senders_immediately(self):
     """
     Model signals registered with model classes as senders don't use the
     Apps.lazy_model_operation() mechanism.
     """
     # Book isn't registered with apps2, so it will linger in
     # apps2._pending_operations if ModelSignal does the wrong thing.
     apps2 = Apps()
     signals.post_init.connect(self.receiver, sender=Book, apps=apps2)
     self.assertEqual(list(apps2._pending_operations), [])
Beispiel #5
0
 def test_dynamic_load(self):
     """
     Makes a new model at runtime and ensures it goes into the right place.
     """
     old_models = list(apps.get_app_config("apps").get_models())
     # Construct a new model in a new app registry
     body = {}
     new_apps = Apps(["apps"])
     meta_contents = {
         'app_label': "apps",
         'apps': new_apps,
     }
     meta = type("Meta", (), meta_contents)
     body['Meta'] = meta
     body['__module__'] = TotallyNormal.__module__
     temp_model = type("SouthPonies", (models.Model,), body)
     # Make sure it appeared in the right place!
     self.assertEqual(list(apps.get_app_config("apps").get_models()), old_models)
     with self.assertRaises(LookupError):
         apps.get_model("apps", "SouthPonies")
     self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model)
Beispiel #6
0
    def test_model_clash(self):
        """
        Test for behavior when two models clash in the app registry.
        """
        new_apps = Apps(["apps"])
        meta_contents = {
            'app_label': "apps",
            'apps': new_apps,
        }

        body = {}
        body['Meta'] = type("Meta", (), meta_contents)
        body['__module__'] = TotallyNormal.__module__
        type("SouthPonies", (models.Model,), body)

        # When __name__ and __module__ match we assume the module
        # was reloaded and issue a warning. This use-case is
        # useful for REPL. Refs #23621.
        body = {}
        body['Meta'] = type("Meta", (), meta_contents)
        body['__module__'] = TotallyNormal.__module__
        msg = (
            "Model 'apps.southponies' was already registered. "
            "Reloading models is not advised as it can lead to inconsistencies, "
            "most notably with related models."
        )
        with self.assertRaisesMessage(RuntimeWarning, msg):
            type("SouthPonies", (models.Model,), body)

        # If it doesn't appear to be a reloaded module then we expect
        # a RuntimeError.
        body = {}
        body['Meta'] = type("Meta", (), meta_contents)
        body['__module__'] = TotallyNormal.__module__ + '.whatever'
        with self.assertRaisesMessage(RuntimeError, "Conflicting 'southponies' models in application 'apps':"):
            type("SouthPonies", (models.Model,), body)
Beispiel #7
0
 def enable(self):
     self.old_apps = Options.default_apps
     apps = Apps(self.installed_apps)
     setattr(Options, 'default_apps', apps)
     return apps
Beispiel #8
0
 def test_singleton_master(self):
     """
     Only one master registry can exist.
     """
     with self.assertRaises(RuntimeError):
         Apps(installed_apps=None)
Beispiel #9
0
 def test_unavailable_content_type_model(self):
     """A ContentType isn't created if the model isn't available."""
     apps = Apps()
     with self.assertNumQueries(0):
         contenttypes_management.create_contenttypes(self.app_config, interactive=False, verbosity=0, apps=apps)
     self.assertEqual(ContentType.objects.count(), self.before_count + 1)
Beispiel #10
0
from djmodels.apps.registry import Apps
from djmodels.db import models

# Because we want to test creation and deletion of these as separate things,
# these models are all inserted into a separate Apps so the main test
# runner doesn't migrate them.

new_apps = Apps()


class Author(models.Model):
    name = models.CharField(max_length=255)
    height = models.PositiveIntegerField(null=True, blank=True)
    weight = models.IntegerField(null=True, blank=True)
    uuid = models.UUIDField(null=True)

    class Meta:
        apps = new_apps


class AuthorCharFieldWithIndex(models.Model):
    char_field = models.CharField(max_length=31, db_index=True)

    class Meta:
        apps = new_apps


class AuthorTextFieldWithIndex(models.Model):
    text_field = models.TextField(db_index=True)

    class Meta:
Beispiel #11
0
    def _remake_table(self,
                      model,
                      create_field=None,
                      delete_field=None,
                      alter_field=None,
                      add_constraint=None,
                      remove_constraint=None):
        """
        Shortcut to transform a model from old_model into new_model

        The essential steps are:
          1. rename the model's existing table, e.g. "app_model" to "app_model__old"
          2. create a table with the updated definition called "app_model"
          3. copy the data from the old renamed table to the new 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
        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,
        # its values must be already quoted.
        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,
        # remove the old one
        restore_pk_field = None
        if getattr(create_field, 'primary_key', False) or (
                alter_field and getattr(alter_field[1], 'primary_key', False)):
            for name, field in list(body.items()):
                if field.primary_key:
                    field.primary_key = False
                    restore_pk_field = field
                    if field.auto_created:
                        del body[name]
                        del mapping[field.column]
        # Add in any created fields
        if create_field:
            body[create_field.name] = create_field
            # Choose a default and insert it into the copy map
            if not create_field.many_to_many and create_field.concrete:
                mapping[create_field.column] = self.quote_value(
                    self.effective_default(create_field))
        # Add in any altered fields
        if alter_field:
            old_field, new_field = alter_field
            body.pop(old_field.name, None)
            mapping.pop(old_field.column, None)
            body[new_field.name] = new_field
            if old_field.null and not new_field.null:
                case_sql = "coalesce(%(col)s, %(default)s)" % {
                    'col': self.quote_name(old_field.column),
                    'default': self.quote_value(
                        self.effective_default(new_field))
                }
                mapping[new_field.column] = case_sql
            else:
                mapping[new_field.column] = self.quote_name(old_field.column)
            rename_mapping[old_field.name] = new_field.name
        # Remove any deleted fields
        if delete_field:
            del body[delete_field.name]
            del mapping[delete_field.column]
            # Remove any implicit M2M tables
            if delete_field.many_to_many and delete_field.remote_field.through._meta.auto_created:
                return self.delete_model(delete_field.remote_field.through)
        # Work inside a new app registry
        apps = Apps()

        # Provide isolated instances of the fields to the new model body so
        # that the existing model's internals aren't interfered with when
        # the dummy model is constructed.
        body = copy.deepcopy(body)

        # Work out the new value of unique_together, taking renames into
        # account
        unique_together = [[rename_mapping.get(n, n) for n in unique]
                           for unique in model._meta.unique_together]

        # Work out the new value for index_together, taking renames into
        # account
        index_together = [[rename_mapping.get(n, n) for n in index]
                          for index in model._meta.index_together]

        indexes = model._meta.indexes
        if delete_field:
            indexes = [
                index for index in indexes
                if delete_field.name not in index.fields
            ]

        constraints = list(model._meta.constraints)
        if add_constraint:
            constraints.append(add_constraint)
        if remove_constraint:
            constraints = [
                constraint for constraint in constraints
                if remove_constraint.name != constraint.name
            ]

        # Construct a new model for the new state
        meta_contents = {
            'app_label': model._meta.app_label,
            'db_table': model._meta.db_table,
            'unique_together': unique_together,
            'index_together': index_together,
            'indexes': indexes,
            'constraints': constraints,
            'apps': apps,
        }
        meta = type("Meta", (), meta_contents)
        body['Meta'] = meta
        body['__module__'] = model.__module__

        temp_model = type(model._meta.object_name, model.__bases__, body)

        # We need to modify model._meta.db_table, but everything explodes
        # if the change isn't reversed before the end of this method. This
        # context manager helps us avoid that situation.
        @contextlib.contextmanager
        def altered_table_name(model, temporary_table_name):
            original_table_name = model._meta.db_table
            model._meta.db_table = temporary_table_name
            yield
            model._meta.db_table = original_table_name

        with altered_table_name(model, model._meta.db_table + "__old"):
            # Rename the old table to make way for the new
            self.alter_db_table(
                model,
                temp_model._meta.db_table,
                model._meta.db_table,
                disable_constraints=False,
            )
            # Create a new table with the updated schema.
            self.create_model(temp_model)

            # Copy data from the old table into the new table
            field_maps = list(mapping.items())
            self.execute("INSERT INTO %s (%s) SELECT %s FROM %s" % (
                self.quote_name(temp_model._meta.db_table),
                ', '.join(self.quote_name(x) for x, y in field_maps),
                ', '.join(y for x, y in field_maps),
                self.quote_name(model._meta.db_table),
            ))

            # Delete the old table
            self.delete_model(model, handle_autom2m=False)

        # Run deferred SQL on correct table
        for sql in self.deferred_sql:
            self.execute(sql)
        self.deferred_sql = []
        # Fix any PK-removed field
        if restore_pk_field:
            restore_pk_field.primary_key = True
Beispiel #12
0
 class Meta:
     apps = Apps()
     app_label = "migrations"
     db_table = "django_migrations"
Beispiel #13
0
from djmodels.apps.registry import Apps
from djmodels.db import models

# We're testing app registry presence on load, so this is handy.

new_apps = Apps(['apps'])


class TotallyNormal(models.Model):
    name = models.CharField(max_length=255)


class SoAlternative(models.Model):
    name = models.CharField(max_length=255)

    class Meta:
        apps = new_apps
Beispiel #14
0
 class Meta:
     # Disable auto loading of this model as we load it on our own
     apps = Apps()
Beispiel #15
0
 class Meta:
     # Disable auto loading of this model as we load it on our own
     apps = Apps()
     verbose_name = 'úñí©óðé µóðéø'
     verbose_name_plural = 'úñí©óðé µóðéøß'