Beispiel #1
0
    def test_models_py(self):
        """
        The models in the models.py file were loaded correctly.
        """
        self.assertEqual(apps.get_model("apps", "TotallyNormal"), TotallyNormal)
        with self.assertRaises(LookupError):
            apps.get_model("apps", "SoAlternative")

        with self.assertRaises(LookupError):
            new_apps.get_model("apps", "TotallyNormal")
        self.assertEqual(new_apps.get_model("apps", "SoAlternative"), SoAlternative)
Beispiel #2
0
 def setUpTestData(cls):
     Site = apps.get_model('sites.Site')
     current_site = Site.objects.get_current()
     current_site.flatpage_set.create(url="/foo/", title="foo")
     current_site.flatpage_set.create(url="/private-foo/",
                                      title="private foo",
                                      registration_required=True)
Beispiel #3
0
def _get_model(model_identifier):
    """Look up a model from an "app_label.model_name" string."""
    try:
        return apps.get_model(model_identifier)
    except (LookupError, TypeError):
        raise base.DeserializationError("Invalid model identifier: '%s'" %
                                        model_identifier)
Beispiel #4
0
def parse_apps_and_model_labels(labels):
    """
    Parse a list of "app_label.ModelName" or "app_label" strings into actual
    objects and return a two-element tuple:
        (set of model classes, set of app_configs).
    Raise a CommandError if some specified models or apps don't exist.
    """
    apps = set()
    models = set()

    for label in labels:
        if '.' in label:
            try:
                model = installed_apps.get_model(label)
            except LookupError:
                raise CommandError('Unknown model: %s' % label)
            models.add(model)
        else:
            try:
                app_config = installed_apps.get_app_config(label)
            except LookupError as e:
                raise CommandError(str(e))
            apps.add(app_config)

    return models, apps
Beispiel #5
0
 def items(self):
     if not django_apps.is_installed('djmodels.contrib.sites'):
         raise ImproperlyConfigured(
             "FlatPageSitemap requires djmodels.contrib.sites, which isn't installed."
         )
     Site = django_apps.get_model('sites.Site')
     current_site = Site.objects.get_current()
     return current_site.flatpage_set.filter(registration_required=False)
Beispiel #6
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 #7
0
def kml(request,
        label,
        model,
        field_name=None,
        compress=False,
        using=DEFAULT_DB_ALIAS):
    """
    This view generates KML for the given app label, model, and field name.

    The field name must be that of a geographic field.
    """
    placemarks = []
    try:
        klass = apps.get_model(label, model)
    except LookupError:
        raise Http404(
            'You must supply a valid app label and module name.  Got "%s.%s"' %
            (label, model))

    if field_name:
        try:
            field = klass._meta.get_field(field_name)
            if not isinstance(field, GeometryField):
                raise FieldDoesNotExist
        except FieldDoesNotExist:
            raise Http404('Invalid geometry field.')

    connection = connections[using]

    if connection.features.has_AsKML_function:
        # Database will take care of transformation.
        placemarks = klass._default_manager.using(using).annotate(
            kml=AsKML(field_name))
    else:
        # If the database offers no KML method, we use the `kml`
        # attribute of the lazy geometry instead.
        placemarks = []
        if connection.features.has_Transform_function:
            qs = klass._default_manager.using(using).annotate(
                **{'%s_4326' % field_name: Transform(field_name, 4326)})
            field_name += '_4326'
        else:
            qs = klass._default_manager.using(using).all()
        for mod in qs:
            mod.kml = getattr(mod, field_name).kml
            placemarks.append(mod)

    # Getting the render function and rendering to the correct.
    if compress:
        render = render_to_kmz
    else:
        render = render_to_kml
    return render('gis/kml/placemarks.kml', {'places': placemarks})
Beispiel #8
0
 def _get_model_from_node(self, node, attr):
     """
     Look up a model from a <object model=...> or a <field rel=... to=...>
     node.
     """
     model_identifier = node.getAttribute(attr)
     if not model_identifier:
         raise base.DeserializationError(
             "<%s> node is missing the required '%s' attribute" %
             (node.nodeName, attr))
     try:
         return apps.get_model(model_identifier)
     except (LookupError, TypeError):
         raise base.DeserializationError(
             "<%s> node has invalid model identifier: '%s'" %
             (node.nodeName, model_identifier))
Beispiel #9
0
def shortcut(request, content_type_id, object_id):
    """
    Redirect to an object's page based on a content-type ID and an object ID.
    """
    # Look up the object, making sure it's got a get_absolute_url() function.
    try:
        content_type = ContentType.objects.get(pk=content_type_id)
        if not content_type.model_class():
            raise Http404(
                _("Content type %(ct_id)s object has no associated model") %
                {'ct_id': content_type_id}
            )
        obj = content_type.get_object_for_this_type(pk=object_id)
    except (ObjectDoesNotExist, ValueError):
        raise Http404(
            _("Content type %(ct_id)s object %(obj_id)s doesn't exist") %
            {'ct_id': content_type_id, 'obj_id': object_id}
        )

    try:
        get_absolute_url = obj.get_absolute_url
    except AttributeError:
        raise Http404(
            _("%(ct_name)s objects don't have a get_absolute_url() method") %
            {'ct_name': content_type.name}
        )
    absurl = get_absolute_url()

    # Try to figure out the object's domain, so we can do a cross-site redirect
    # if necessary.

    # If the object actually defines a domain, we're done.
    if absurl.startswith(('http://', 'https://', '//')):
        return HttpResponseRedirect(absurl)

    # Otherwise, we need to introspect the object's relationships for a
    # relation to the Site object
    try:
        object_domain = get_current_site(request).domain
    except ObjectDoesNotExist:
        object_domain = None

    if apps.is_installed('djmodels.contrib.sites'):
        Site = apps.get_model('sites.Site')
        opts = obj._meta

        for field in opts.many_to_many:
            # Look for a many-to-many relationship to Site.
            if field.remote_field.model is Site:
                site_qs = getattr(obj, field.name).all()
                if object_domain and site_qs.filter(domain=object_domain).exists():
                    # The current site's domain matches a site attached to the
                    # object.
                    break
                # Caveat: In the case of multiple related Sites, this just
                # selects the *first* one, which is arbitrary.
                site = site_qs.first()
                if site:
                    object_domain = site.domain
                    break
        else:
            # No many-to-many relationship to Site found. Look for a
            # many-to-one relationship to Site.
            for field in obj._meta.fields:
                if field.remote_field and field.remote_field.model is Site:
                    try:
                        site = getattr(obj, field.name)
                    except Site.DoesNotExist:
                        continue
                    if site is not None:
                        object_domain = site.domain
                        break

    # If all that malarkey found an object domain, use it. Otherwise, fall back
    # to whatever get_absolute_url() returned.
    if object_domain is not None:
        protocol = request.scheme
        return HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
    else:
        return HttpResponseRedirect(absurl)
Beispiel #10
0
    def test_get_model(self):
        """
        Tests apps.get_model().
        """
        self.assertEqual(apps.get_model('admin', 'LogEntry'), LogEntry)
        with self.assertRaises(LookupError):
            apps.get_model('admin', 'LogExit')

        # App label is case-sensitive, Model name is case-insensitive.
        self.assertEqual(apps.get_model('admin', 'loGentrY'), LogEntry)
        with self.assertRaises(LookupError):
            apps.get_model('Admin', 'LogEntry')

        # A single argument is accepted.
        self.assertEqual(apps.get_model('admin.LogEntry'), LogEntry)
        with self.assertRaises(LookupError):
            apps.get_model('admin.LogExit')
        with self.assertRaises(ValueError):
            apps.get_model('admin_LogEntry')
Beispiel #11
0
def sort_dependencies(app_list):
    """Sort a list of (app_config, models) pairs into a single list of models.

    The single list of models is sorted so that any model with a natural key
    is serialized before a normal model, and any model with a natural key
    dependency has it's dependencies serialized first.
    """
    # Process the list of models, and get the list of dependencies
    model_dependencies = []
    models = set()
    for app_config, model_list in app_list:
        if model_list is None:
            model_list = app_config.get_models()

        for model in model_list:
            models.add(model)
            # Add any explicitly defined dependencies
            if hasattr(model, 'natural_key'):
                deps = getattr(model.natural_key, 'dependencies', [])
                if deps:
                    deps = [apps.get_model(dep) for dep in deps]
            else:
                deps = []

            # Now add a dependency for any FK relation with a model that
            # defines a natural key
            for field in model._meta.fields:
                if field.remote_field:
                    rel_model = field.remote_field.model
                    if hasattr(rel_model,
                               'natural_key') and rel_model != model:
                        deps.append(rel_model)
            # Also add a dependency for any simple M2M relation with a model
            # that defines a natural key.  M2M relations with explicit through
            # models don't count as dependencies.
            for field in model._meta.many_to_many:
                if field.remote_field.through._meta.auto_created:
                    rel_model = field.remote_field.model
                    if hasattr(rel_model,
                               'natural_key') and rel_model != model:
                        deps.append(rel_model)
            model_dependencies.append((model, deps))

    model_dependencies.reverse()
    # Now sort the models to ensure that dependencies are met. This
    # is done by repeatedly iterating over the input list of models.
    # If all the dependencies of a given model are in the final list,
    # that model is promoted to the end of the final list. This process
    # continues until the input list is empty, or we do a full iteration
    # over the input models without promoting a model to the final list.
    # If we do a full iteration without a promotion, that means there are
    # circular dependencies in the list.
    model_list = []
    while model_dependencies:
        skipped = []
        changed = False
        while model_dependencies:
            model, deps = model_dependencies.pop()

            # If all of the models in the dependency list are either already
            # on the final model list, or not on the original serialization list,
            # then we've found another model with all it's dependencies satisfied.
            if all(d not in models or d in model_list for d in deps):
                model_list.append(model)
                changed = True
            else:
                skipped.append((model, deps))
        if not changed:
            raise RuntimeError(
                "Can't resolve dependencies for %s in serialized app list." %
                ', '.join('%s.%s' %
                          (model._meta.app_label, model._meta.object_name)
                          for model, deps in sorted(
                              skipped, key=lambda obj: obj[0].__name__)))
        model_dependencies = skipped

    return model_list
Beispiel #12
0
    def handle(self, *args, **options):

        self.verbosity = options['verbosity']
        self.interactive = options['interactive']

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        for app_config in apps.get_app_configs():
            if module_has_submodule(app_config.module, "management"):
                import_module('.management', app_config.name)

        # Get the database we're operating from
        db = options['database']
        connection = connections[db]

        # Hook for backends needing any database preparation
        connection.prepare_database()
        # Work out which apps have migrations and which do not
        executor = MigrationExecutor(connection, self.migration_progress_callback)

        # Raise an error if any migrations are applied before their dependencies.
        executor.loader.check_consistent_history(connection)

        # Before anything else, see if there's conflicting apps and drop out
        # hard if there are any
        conflicts = executor.loader.detect_conflicts()
        if conflicts:
            name_str = "; ".join(
                "%s in %s" % (", ".join(names), app)
                for app, names in conflicts.items()
            )
            raise CommandError(
                "Conflicting migrations detected; multiple leaf nodes in the "
                "migration graph: (%s).\nTo fix them run "
                "'python manage.py makemigrations --merge'" % name_str
            )

        # If they supplied command line arguments, work out what they mean.
        target_app_labels_only = True
        if options['app_label']:
            # Validate app_label.
            app_label = options['app_label']
            try:
                apps.get_app_config(app_label)
            except LookupError as err:
                raise CommandError(str(err))
            if app_label not in executor.loader.migrated_apps:
                raise CommandError("App '%s' does not have migrations." % app_label)

        if options['app_label'] and options['migration_name']:
            migration_name = options['migration_name']
            if migration_name == "zero":
                targets = [(app_label, None)]
            else:
                try:
                    migration = executor.loader.get_migration_by_prefix(app_label, migration_name)
                except AmbiguityError:
                    raise CommandError(
                        "More than one migration matches '%s' in app '%s'. "
                        "Please be more specific." %
                        (migration_name, app_label)
                    )
                except KeyError:
                    raise CommandError("Cannot find a migration matching '%s' from app '%s'." % (
                        migration_name, app_label))
                targets = [(app_label, migration.name)]
            target_app_labels_only = False
        elif options['app_label']:
            targets = [key for key in executor.loader.graph.leaf_nodes() if key[0] == app_label]
        else:
            targets = executor.loader.graph.leaf_nodes()

        plan = executor.migration_plan(targets)

        if options['plan']:
            self.stdout.write('Planned operations:', self.style.MIGRATE_LABEL)
            if not plan:
                self.stdout.write('  No planned migration operations.')
            for migration, backwards in plan:
                self.stdout.write(str(migration), self.style.MIGRATE_HEADING)
                for operation in migration.operations:
                    message, is_error = self.describe_operation(operation, backwards)
                    style = self.style.WARNING if is_error else None
                    self.stdout.write('    ' + message, style)
            return

        run_syncdb = options['run_syncdb'] and executor.loader.unmigrated_apps
        # Print some useful info
        if self.verbosity >= 1:
            self.stdout.write(self.style.MIGRATE_HEADING("Operations to perform:"))
            if run_syncdb:
                self.stdout.write(
                    self.style.MIGRATE_LABEL("  Synchronize unmigrated apps: ") +
                    (", ".join(sorted(executor.loader.unmigrated_apps)))
                )
            if target_app_labels_only:
                self.stdout.write(
                    self.style.MIGRATE_LABEL("  Apply all migrations: ") +
                    (", ".join(sorted({a for a, n in targets})) or "(none)")
                )
            else:
                if targets[0][1] is None:
                    self.stdout.write(self.style.MIGRATE_LABEL(
                        "  Unapply all migrations: ") + "%s" % (targets[0][0],)
                    )
                else:
                    self.stdout.write(self.style.MIGRATE_LABEL(
                        "  Target specific migration: ") + "%s, from %s"
                        % (targets[0][1], targets[0][0])
                    )

        pre_migrate_state = executor._create_project_state(with_applied_migrations=True)
        pre_migrate_apps = pre_migrate_state.apps
        emit_pre_migrate_signal(
            self.verbosity, self.interactive, connection.alias, apps=pre_migrate_apps, plan=plan,
        )

        # Run the syncdb phase.
        if run_syncdb:
            if self.verbosity >= 1:
                self.stdout.write(self.style.MIGRATE_HEADING("Synchronizing apps without migrations:"))
            self.sync_apps(connection, executor.loader.unmigrated_apps)

        # Migrate!
        if self.verbosity >= 1:
            self.stdout.write(self.style.MIGRATE_HEADING("Running migrations:"))
        if not plan:
            if self.verbosity >= 1:
                self.stdout.write("  No migrations to apply.")
                # If there's changes that aren't in migrations yet, tell them how to fix it.
                autodetector = MigrationAutodetector(
                    executor.loader.project_state(),
                    ProjectState.from_apps(apps),
                )
                changes = autodetector.changes(graph=executor.loader.graph)
                if changes:
                    self.stdout.write(self.style.NOTICE(
                        "  Your models have changes that are not yet reflected "
                        "in a migration, and so won't be applied."
                    ))
                    self.stdout.write(self.style.NOTICE(
                        "  Run 'manage.py makemigrations' to make new "
                        "migrations, and then re-run 'manage.py migrate' to "
                        "apply them."
                    ))
            fake = False
            fake_initial = False
        else:
            fake = options['fake']
            fake_initial = options['fake_initial']
        post_migrate_state = executor.migrate(
            targets, plan=plan, state=pre_migrate_state.clone(), fake=fake,
            fake_initial=fake_initial,
        )
        # post_migrate signals have access to all models. Ensure that all models
        # are reloaded in case any are delayed.
        post_migrate_state.clear_delayed_apps_cache()
        post_migrate_apps = post_migrate_state.apps

        # Re-render models of real apps to include relationships now that
        # we've got a final state. This wouldn't be necessary if real apps
        # models were rendered with relationships in the first place.
        with post_migrate_apps.bulk_update():
            model_keys = []
            for model_state in post_migrate_apps.real_models:
                model_key = model_state.app_label, model_state.name_lower
                model_keys.append(model_key)
                post_migrate_apps.unregister_model(*model_key)
        post_migrate_apps.render_multiple([
            ModelState.from_model(apps.get_model(*model)) for model in model_keys
        ])

        # Send the post_migrate signal, so individual apps can do whatever they need
        # to do at this point.
        emit_post_migrate_signal(
            self.verbosity, self.interactive, connection.alias, apps=post_migrate_apps, plan=plan,
        )
Beispiel #13
0
 def model_class(self):
     """Return the model class for this type of content."""
     try:
         return apps.get_model(self.app_label, self.model)
     except LookupError:
         return None
Beispiel #14
0
 def test_get_model_only_returns_installed_models(self):
     with self.assertRaises(LookupError):
         apps.get_model("not_installed", "NotInstalledModel")