Example #1
0
    def test_app(self):
        info = meta.model_info(Owner)
        self.assertIs(info.app_config,
                      apps.get_containing_app_config(Owner.__module__))

        info = meta.model_info(OtherAppInOtherApp)
        self.assertIs(info.app_config,
                      apps.get_containing_app_config(Owner.__module__))
Example #2
0
 def test_get_containing_app_config_apps_not_ready(self):
     """
     apps.get_containing_app_config() should raise an exception if
     apps.apps_ready isn't True.
     """
     apps.apps_ready = False
     try:
         with self.assertRaisesMessage(AppRegistryNotReady, "Apps aren't loaded yet"):
             apps.get_containing_app_config('foo')
     finally:
         apps.apps_ready = True
Example #3
0
 def test_get_containing_app_config_apps_not_ready(self):
     """
     apps.get_containing_app_config() should raise an exception if
     apps.apps_ready isn't True.
     """
     apps.apps_ready = False
     try:
         with self.assertRaisesMessage(AppRegistryNotReady, "Apps aren't loaded yet"):
             apps.get_containing_app_config('foo')
     finally:
         apps.apps_ready = True
Example #4
0
def get_service_type(model):
    try:
        return model.get_service_name()
    except AttributeError:
        pass
    app_config = apps.get_containing_app_config(model.__module__)
    return getattr(app_config, 'service_name', None)
Example #5
0
    def setUp(self):
        super(TestModelsLoaderMixin, self).setUp()

        # If we made a fake 'models' module, add it to sys.modules.
        models_mod = self._tests_loader_models_mod

        if models_mod:
            sys.modules[models_mod.__name__] = models_mod

        self._models_loader_old_settings = settings.INSTALLED_APPS
        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + [
            self.tests_app,
        ]

        if apps:
            # Push the new set of installed apps, and begin registering
            # each of the models associated with the tests.
            apps.set_installed_apps(settings.INSTALLED_APPS)
            app_config = apps.get_containing_app_config(self.tests_app)

            for key, value in six.iteritems(models_mod.__dict__):
                if inspect.isclass(value) and issubclass(value, Model):
                    apps.register_model(app_config.label, value)

            call_command('migrate', verbosity=0, interactive=False)
        else:
            load_app(self.tests_app)
            call_command('syncdb', verbosity=0, interactive=False)
Example #6
0
 def sorcery_apps(self):
     """
     All sorcery apps and their alembic configs
     """
     configs = OrderedDict()
     for db in databases.values():
         table_class_map = {model.__table__: model for model in db.models_registry if hasattr(model, "__table__")}
         for table in db.metadata.sorted_tables:
             model = table_class_map.get(table)
             if model:
                 app = apps.get_containing_app_config(model.__module__)
                 if app:
                     path = self.get_app_version_path(app)
                     if os.path.exists(path):
                         config = self.get_app_config(app, db)
                         appconfig = AlembicAppConfig(
                             name=app.label,
                             config=config,
                             db=db,
                             script=self.get_config_script(config),
                             version_path=path,
                             app=app,
                             tables=[],
                         )
                         configs.setdefault(app.label, appconfig).tables.append(table)
     for app in configs.values():
         signals.alembic_app_created.send(app.app)
         signals.alembic_config_created.send(app.config)
     return configs
Example #7
0
    def get_tested_locations(self, test_labels):
        locations = []

        if test_labels:
            pass
        elif hasattr(settings, "PROJECT_APPS"):
            test_labels = settings.PROJECT_APPS
        else:
            warnings.warn("No PROJECTS_APPS settings, coverage gathered over all apps")
            test_labels = settings.INSTALLED_APPS

        try:
            from django.apps import apps

            for test_label in test_labels:
                app_config = apps.get_containing_app_config(test_label)
                locations.append(os.path.dirname(app_config.module.__file__))
        except ImportError:
            # django 1.6
            from django.db.models import get_app

            for test_label in test_labels:
                models_module = get_app(test_label.split(".")[-1])
                locations.append(os.path.dirname(models_module.__file__))

        return locations
Example #8
0
 def default_app_label(self):
     """ Get default app Label. """
     if self.APP_LABEL is None:
         return apps.get_containing_app_config(
             self.__class__.__module__).label
     else:
         return self.APP_LABEL
Example #9
0
    def get_tested_locations(self, test_labels):
        locations = []

        coverage = apps.get_app_config('django_jenkins').coverage
        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        elif coverage and coverage.coverage.source:
            warnings.warn(
                "No PROJECT_APPS settings, using 'source' config from rcfile")
            locations = coverage.coverage.source
        else:
            warnings.warn(
                'No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        for test_label in test_labels:
            app_config = apps.get_containing_app_config(test_label)
            if app_config is not None:
                locations.append(app_config.path)
            else:
                warnings.warn('No app found for test: {0}'.format(test_label))

        return locations
Example #10
0
def get_task_ref(flow_task):
    module = flow_task.flow_cls.__module__
    app_config = apps.get_containing_app_config(module)
    subpath = module.lstrip(app_config.module.__package__ + '.')

    return "{}/{}.{}.{}".format(app_config.label, subpath,
                                flow_task.flow_cls.__name__, flow_task.name)
Example #11
0
    def type_def(self, type_def):
        if isinstance(type_def, str):
            type_def = import_string(type_def)

        if not issubclass(type_def, self.type_def_subclass):
            raise TypeError('type_def must be a subclass of {}'.format(
                self.type_def_subclass))

        # Import meta options from type_def
        with suppress(AttributeError):
            self.type_name = type_def.Meta.db_type
        with suppress(AttributeError):
            self.type_app_label = type_def.Meta.app_label

        if not self.type_app_label:
            # Determine app_label of enum being used
            app_config = apps.get_containing_app_config(type_def.__module__)
            if app_config is None:
                raise RuntimeError(
                    "type_def class doesn't declare an explicit app_label, and isn't"
                    " in an application in INSTALLED_APPS")
            self.type_app_label = app_config.label

        # Generate type_name if not already set
        if not self.type_name:
            self.type_name = '{app_label}_{type_subclass}_{type_name}'.format(
                app_label=self.type_app_label,
                type_subclass=self.type_def_subclass.__name__.lower(),
                type_name=type_def.__qualname__.lower())

        self._type_def = type_def
Example #12
0
    def setUp(self):
        super(TestModelsLoaderMixin, self).setUp()

        # If we made a fake 'models' module, add it to sys.modules.
        models_mod = self._tests_loader_models_mod

        if models_mod:
            sys.modules[models_mod.__name__] = models_mod

        self._models_loader_old_settings = settings.INSTALLED_APPS
        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + [
            self.tests_app,
        ]

        if apps:
            # Push the new set of installed apps, and begin registering
            # each of the models associated with the tests.
            apps.set_installed_apps(settings.INSTALLED_APPS)
            app_config = apps.get_containing_app_config(self.tests_app)

            if models_mod:
                for key, value in six.iteritems(models_mod.__dict__):
                    if inspect.isclass(value) and issubclass(value, Model):
                        apps.register_model(app_config.label, value)

            call_command('migrate', verbosity=0, interactive=False)
        else:
            load_app(self.tests_app)
            call_command('syncdb', verbosity=0, interactive=False)
Example #13
0
 def get_containing_app_data(module):
     """
     Return app label and package string
     """
     app_config = apps.get_containing_app_config(module)
     if not app_config:
         return None, None
     return app_config.label, app_config.module.__name__
Example #14
0
 def get_containing_app_data(module):
     """
     Return app label and package string
     """
     app_config = apps.get_containing_app_config(module)
     if not app_config:
         return None, None
     return app_config.label, app_config.module.__name__
 def app(self):
     try:
         return apps.get_containing_app_config(
             self.__module__).name.split('.')[-1]
     except AttributeError:
         raise AppNotFound()
     finally:
         return None
Example #16
0
 def get_model_template_name(self):
     """Returns the base template path."""
     model = self.get_model()
     app_config = apps.get_containing_app_config(model.__module__)
     return "{}/{}{}.html".format(
         model.__name__.lower() if app_config is None else app_config.label,
         model.__name__.lower(),
         self.template_name_suffix,
     )
Example #17
0
    def get_urls(self):
        urlpatterns = []

        for report in self._registry:
            app_name = apps.get_containing_app_config(report.__module__).name
            urlpatterns.append(
                url(r"^%s/%s/" % (app_name, report.__name__.lower()),
                    ReportView.as_view(report_class=report),
                    name=camel_re.sub(r'\1_\2', report.__name__).lower()))
        return urlpatterns
Example #18
0
def setup_test_app(package, label=None):
    """
    Setup a Django test app for the provided package to allow test-only models
    to be used.
    This function should be called from myapp.tests.__init__ like so:

        setup_test_app(__package__)

    Or, if a specific app label is required, like so:

        setup_test_app(__package__, 'mytests')

    Models defined within the package also require their app labels manually
    set to match, e.g.:

        class MyTestModel(models.Model):

            # ...

            class Meta:
                app_label = 'mytests'
    """

    #
    #

    if label is None:
        containing_app_config = apps.get_containing_app_config(package)
        label = containing_app_config.label

        # Only suffix the app label if it has not been already. This allows
        # duplicate entries to be detected and prevented. It may prevent the
        # use of an implicit label if the tests reside in an app that
        # legitimately ends with "_tests", but an explicit label can always be
        # used. Without this check, earlier entries are returned by
        # get_containing_app_config() and suffixed repeatedly.
        if not containing_app_config.label.endswith('_tests'):
            label = '{}_tests'.format(containing_app_config.label)

    if label in apps.app_configs:
        # An app with this label already exists, skip adding it. This is
        # necessary (vs raising an exception) as there are certain conditions
        # that can cause this function to be run multiple times (e.g. errors
        # during Django's initialisation can cause this).
        return

    app_config = AppConfig.create(package)
    app_config.apps = apps
    app_config.label = label

    apps.app_configs[label] = app_config

    app_config.import_models()

    apps.clear_cache()
Example #19
0
    def __new__(mcs, name, bases, attrs):
        super_new = super().__new__

        parents = [b for b in bases if isinstance(b, _CollectionBaseMetaclass)]
        if not parents:
            return super_new(mcs, name, bases, attrs)

        module = attrs.pop('__module__')
        new_attrs = {'__module__': module}
        classcell = attrs.pop('__classcell__', None)
        if classcell is not None:
            new_attrs['__classcell__'] = classcell
        new_class = super_new(mcs, name, bases, new_attrs)
        attr_meta = attrs.pop('Meta', None)

        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        app_label = None

        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, 'app_label', None) is None:
            if app_config is None:
                raise RuntimeError(
                    "resources class %s.%s doesn't declare an explicit "
                    "app_label and isn't in an application in "
                    "INSTALLED_APPS." % (module, name))

            else:
                app_label = app_config.label

        meta = new_class._get_options_class()(meta, app_label)
        meta.contribute_to_class(new_class, '_meta')

        for parent in parents:
            if hasattr(parent, '_meta') and parent._meta:
                for field, value in parent._meta.fields.items():
                    if field not in attrs:
                        attrs[field] = copy.copy(value)

        if 'client' not in attrs:
            new_class.client = meta.client_class()
            new_class.client.contribute_to_class(new_class, 'client')

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        new_class.register_class()

        return new_class
Example #20
0
    def get_prep_value(self, value):
        if not isinstance(value, type):
            # HACK: Django calls callable due query parameter
            # preparation. So here we can get Flow instance,
            # even if we pass Flow class to query.
            value = value.__class__

        module = "{}.{}".format(value.__module__, value.__name__)
        app_config = apps.get_containing_app_config(module)
        subpath = module.lstrip(app_config.module.__package__+'.')
        return "{}/{}".format(app_config.label, subpath)
Example #21
0
 def current_app_name(self):
     app_config = django_apps.get_containing_app_config(
         self.__class__.__module__,
     )
     name = None
     if app_config:
         name = app_config.name
         module_prefix = self.apps_module + '.'
         if name.startswith(module_prefix):
             name = name[len(module_prefix):]
     return name
Example #22
0
    def get_prep_value(self, value):
        if not isinstance(value, type):
            # HACK: Django calls callable due query parameter
            # preparation. So here we can get Flow instance,
            # even if we pass Flow class to query.
            value = value.__class__

        module = "{}.{}".format(value.__module__, value.__name__)
        app_config = apps.get_containing_app_config(module)
        subpath = module.lstrip(app_config.module.__package__ + '.')
        return "{}/{}".format(app_config.label, subpath)
    def get_urls(self):
        urlpatterns = []

        for report in self._registry:
            app_name = apps.get_containing_app_config(report.__module__).name
            urlpatterns.append(
                url(r"^{0}/{1}/$".format(app_name.replace(".", "_"), report.__name__.lower()),
                    ReportView.as_view(report_class=report),
                    name=camel_re.sub(r'\1_\2', report.__name__).lower()
                ))
        return urlpatterns
Example #24
0
    def __new__(cls, name, bases, attrs):
        super_new = super(constructor, cls).__new__
        parents = [b for b in bases if isinstance(b, constructor)]
        if not parents:
            return super_new(cls, name, bases, attrs)

        module = attrs.pop('__module__', None)
        new_class = super_new(cls, name, bases, attrs)
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', ServiceOptions)
        else:
            params = {
                key: value
                for key, value in attr_meta.__dict__.items()
                if not key.startswith('__') and not callable(key)
            }
            SubClass = type(attr_meta.__name__, (ServiceOptions, ), params)
            meta = SubClass
        base_meta = getattr(new_class, '_meta', None)

        app_label = None
        app_config = apps.get_containing_app_config(module)
        if getattr(meta, 'app_label', None) is None:
            if app_config is None:
                raise RuntimeError(
                    "Model class %s.%s doesn't declare an explicit "
                    "app_label and isn't in an application in "
                    "INSTALLED_APPS." % (module, name))
            else:
                app_label = app_config.label
        _service_fields = getattr(meta, '_service_fields', None)

        # import pdb
        # pdb.set_trace()

        dm = attrs.pop('_default_manager', BaseManager)
        service = attrs.pop('_service_api', None)
        if not _service_fields:
            _service_fields = service.initialize()
            # import ipdb; ipdb.set_trace()
        new_class.add_to_class(
            '_meta',
            meta(meta,
                 app_label=app_label,
                 the_class=new_class,
                 _service_fields=_service_fields))

        # import pdb; pdb.set_trace()
        if dm:
            new_class._default_manager = dm(new_class, mailer=service)
            new_class.objects = new_class._default_manager

        return new_class
Example #25
0
    def __new__(cls, name, bases, attrs):
        new_class = super(FlowMetaClass, cls).__new__(cls, name, bases, attrs)

        # singleton instance
        new_class.instance = FlowInstanceDescriptor()

        # set up flow tasks
        nodes = {name: attr for name, attr in attrs.items() if isinstance(attr, flow.Node)}

        for name, node in nodes.items():
            node.name = name

        resolver = Resolver(nodes)
        for node in nodes.values():
            resolver.resolve_children_links(node)

        incoming = defaultdict(lambda: [])  # node -> [incoming_nodes]
        for _, node in nodes.items():
            for outgoing_edge in node._outgoing():
                incoming[outgoing_edge.dst].append(outgoing_edge)
        for target, edges in incoming.items():
            target._incoming_edges = edges

        # set up workflow meta
        app_config = apps.get_containing_app_config(new_class.__module__)

        if app_config is None:
            raise ImportError("Flow can't be imported before app setup")
        new_class._meta = FlowMeta(app_config.label, new_class, nodes)

        # flow back reference
        for name, node in nodes.items():
            node.flow_cls = new_class

        # description
        if new_class.__doc__:
            docstring = new_class.__doc__.split('\n\n', maxsplit=1)
            if 'process_title' not in attrs and len(docstring) > 0:
                new_class.process_title = docstring[0].strip()
            if 'process_description' not in attrs and len(docstring) > 1:
                new_class.process_description = docstring[1].strip()

        # index view
        if not getattr(new_class, 'index_view', None):
            from viewflow.views import index
            new_class.index_view = index
            new_class.index_view = staticmethod(new_class.index_view)

        # done flow setup
        for name, node in nodes.items():
            node.ready()

        return new_class
Example #26
0
    def get_urls(self):
        urlpatterns = []

        for report in self._registry:
            app_name = apps.get_containing_app_config(report.__module__).name
            urlpatterns.append(
                url(r"^{0}/{1}/$".format(app_name.replace(".", "_"),
                                         report.__name__.lower()),
                    admin_site.admin_view(
                        ReportView.as_view(report_class=report)),
                    name=camel_re.sub(r'\1_\2', report.__name__).lower()))
        return urlpatterns
Example #27
0
    def __new__(cls, name, bases, attrs):
        new_class = super(FlowMetaClass, cls).__new__(cls, name, bases, attrs)

        # singleton instance
        new_class.instance = FlowInstanceDescriptor()

        # set up flow tasks
        nodes = {
            name: attr
            for name, attr in attrs.items() if isinstance(attr, flow.Node)
        }

        for name, node in nodes.items():
            node.name = name

        resolver = Resolver(nodes)
        for node in nodes.values():
            resolver.resolve_children_links(node)

        incoming = defaultdict(lambda: [])  # node -> [incoming_nodes]
        for _, node in nodes.items():
            for outgoing_edge in node._outgoing():
                incoming[outgoing_edge.dst].append(outgoing_edge)
        for target, edges in incoming.items():
            target._incoming_edges = edges

        # set up workflow meta
        app_config = apps.get_containing_app_config(new_class.__module__)

        if app_config is None:
            raise ImportError("Flow can't be imported before app setup")
        new_class._meta = FlowMeta(app_config.label, new_class, nodes)

        # flow back reference
        for name, node in nodes.items():
            node.flow_cls = new_class

        # description
        if new_class.__doc__:
            docstring = new_class.__doc__.split('\n\n', maxsplit=1)
            if 'process_title' not in attrs and len(docstring) > 0:
                new_class.process_title = docstring[0].strip()
            if 'process_description' not in attrs and len(docstring) > 1:
                new_class.process_description = docstring[1].strip()

        # done flow setup
        for name, node in nodes.items():
            node.ready()

        return new_class
Example #28
0
    def initialize_type(cls, types=DEFAULT_SPECS, **kwargs):
        if not apps.get_containing_app_config('feincms.module.medialibrary'):
            raise (ImproperlyConfigured,
                   'You have to add \'feincms.module.medialibrary\' to your '
                   'INSTALLED_APPS before creating a %s' % cls.__name__)

        cls.specs = dict([('%s_%s' % (spec.name, types.index(spec)), spec)
                          for spec in types])
        cls.spec_choices = [(spec, cls.specs[spec].verbose_name)
                            for spec in cls.specs]
        cls.add_to_class(
            'type',
            models.CharField(max_length=20,
                             choices=cls.spec_choices,
                             default=cls.spec_choices[0][0]))
Example #29
0
def migration_hook(request):
    '''
    Pause migration at the migration named in @pytest.mark.migrate_from('0001-initial-migration')

    The migration_hook param will be a callable to then trigger the migration named in:
        @pytest.mark.migrate_from('0002-migrate-things')

    migration_hook also has an 'apps' attribute which is used to lookup models in the current migration state

    eg.
        MyModel = migration_hook.apps.get_model('myapp', 'MyModel')

    based on: https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/
    '''

    migrate_from_mark = request.node.get_closest_marker('migrate_from')
    assert migrate_from_mark, 'must mark the migration to stop at with @pytest.mark.migrate_from()'
    assert len(migrate_from_mark.args) == 1, 'migrate_from mark expects 1 arg'
    assert not migrate_from_mark.kwargs, 'migrate_from mark takes no keywords'
    migrate_to_mark = request.node.get_closest_marker('migrate_to')
    assert migrate_to_mark, 'must mark the migration to hook with @pytest.mark.migrate_to()'
    assert len(migrate_to_mark.args) == 1, 'migrate_to mark expects 1 arg'
    assert not migrate_to_mark.kwargs, 'migrate_to mark takes no keywords'

    app = apps.get_containing_app_config(request.module.__name__).name

    migrate_from = [(app, migrate_from_mark.args[0])]
    migrate_to = [(app, migrate_to_mark.args[0])]

    class migration_hook_result(object):

        def __init__(self, _from, _to):
            self._to = _to
            executor = MigrationExecutor(connection)
            self.apps = executor.loader.project_state(_from).apps

            # Reverse to the original migration
            executor.migrate(_from)

        def __call__(self):
            # Run the migration to test
            executor = MigrationExecutor(connection)
            executor.loader.build_graph()  # reload.
            executor.migrate(self._to)

            self.apps = executor.loader.project_state(self._to).apps

    yield migration_hook_result(migrate_from, migrate_to)
    def _create_test_model(
        self, base_class=models.Model, fields=None, model_name=None,
        options=None
    ):
        self.model_name = model_name or 'TestModel'
        self.options = options
        # Obtain the app_config and app_label from the test's module path
        self.app_config = apps.get_containing_app_config(
            object_name=self.__class__.__module__
        )

        if connection.vendor == 'mysql':
            self.skipTest(
                reason='MySQL doesn\'t support schema changes inside an '
                'atomic block.'
            )

        attrs = {
            '__module__': self.__class__.__module__,
            'save': self._get_test_model_save_method(),
            'Meta': self._get_test_model_meta(),
        }

        if fields:
            attrs.update(fields)

        # Clear previous model registration before re-registering it again to
        # avoid conflict with test models with the same name, in the same app
        # but from another test module.
        apps.all_models[self.app_config.label].pop(self.model_name.lower(), None)

        if PY3:
            model = type(
                self.model_name, (base_class,), attrs
            )
        else:
            model = type(
                force_bytes(self.model_name), (base_class,), attrs
            )

        if not model._meta.proxy:
            with connection.schema_editor() as schema_editor:
                schema_editor.create_model(model=model)

        self._test_models.append(model)
        ContentType.objects.clear_cache()

        return model
Example #31
0
    def _update_plugin(self, plugin_name):
        # Import here to prevent circular import
        from kolibri.plugins.registry import registered_plugins

        app_configs = []
        plugin_instance = registered_plugins.get(plugin_name)
        if plugin_instance is None:
            logger.error(
                "Tried to run upgrades for plugin {} but it doesn't exist".
                format(plugin_name))
            return
        for app in plugin_instance.INSTALLED_APPS:
            if not isinstance(app, AppConfig) and isinstance(app, str):
                app = apps.get_containing_app_config(app)
            app_configs.append(app)
        old_version = config["PLUGIN_VERSIONS"].get(plugin_name, "")
        new_version = _get_plugin_version(plugin_name)
        try:
            self._migrate_plugin(plugin_name, app_configs)
        except Exception as e:
            logger.error(
                "Unhandled exception while migrating {}, exception was:\n\n{}".
                format(plugin_name, e))
            return
        if old_version:
            if VersionInfo.parse(normalize_version_to_semver(
                    old_version)) < VersionInfo.parse(
                        normalize_version_to_semver(new_version)):
                logger.info(
                    "Running upgrade routines for {}, upgrading from {} to {}".
                    format(plugin_name, old_version, new_version))
            else:
                logger.info(
                    "Running downgrade routines for {}, downgrading from {} to {}"
                    .format(plugin_name, old_version, new_version))
        else:
            logger.info(
                "Running installation routines for {}, installing {}".format(
                    plugin_name, new_version))
        try:
            run_upgrades(old_version, new_version, app_configs=app_configs)
        except Exception as e:
            logger.error(
                "An exception occured running upgrades for plugin {}: {}".
                format(plugin_name, e))
            return
        return new_version
Example #32
0
    def __new__(mcls, name, bases, attrs):  # noqa: B902

        meta = attrs.get("Meta", None)
        module = attrs.get("__module__")

        new_cls = super(MetricMeta, mcls).__new__(mcls, name, bases, attrs)
        # Also ensure initialization is only performed for subclasses of Metric
        # (excluding Metric class itself).
        if not any(
            b for b in bases if isinstance(b, MetricMeta) and b is not BaseMetric
        ):
            return new_cls

        template_name = getattr(meta, "template_name", None)
        template = getattr(meta, "template", None)
        abstract = getattr(meta, "abstract", False)

        app_label = getattr(meta, "app_label", None)
        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)
        if app_label is None:
            if app_config is None:
                if not abstract:
                    raise RuntimeError(
                        "Metric class %s.%s doesn't declare an explicit "
                        "app_label and isn't in an application in "
                        "INSTALLED_APPS." % (module, name)
                    )
            else:
                app_label = app_config.label

        if not template_name or not template:
            metric_name = new_cls.__name__.lower()
            # If template_name not specified in class Meta,
            # compute it as <app label>_<lowercased class name>
            if not template_name:
                template_name = "{}_{}".format(app_label, metric_name)
            # template is <app label>_<lowercased class name>-*
            template = template or "{}_{}_*".format(app_label, metric_name)

        new_cls._template_name = template_name
        new_cls._template = template
        # Abstract base metrics can't be instantiated and don't appear in
        # the list of metrics for an app.
        if not abstract:
            registry.register(app_label, new_cls)
        return new_cls
Example #33
0
    def get_tested_locations(self, test_labels):
        locations = []

        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        else:
            warnings.warn(
                'No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        try:
            from django.apps import apps
            for test_label in test_labels:
                app_config = apps.get_containing_app_config(test_label)
                if app_config is not None:
                    locations.append(
                        os.path.dirname(app_config.module.__file__))
                else:
                    warnings.warn(
                        'No app found for test: {0}'.format(test_label))
        except ImportError:
            # django 1.6
            from django.utils.importlib import import_module

            def get_containing_app(object_name):
                candidates = []
                for app_label in settings.INSTALLED_APPS:
                    if object_name.startswith(app_label):
                        subpath = object_name[len(app_label):]
                        if subpath == '' or subpath[0] == '.':
                            candidates.append(app_label)
                if candidates:
                    return sorted(candidates, key=lambda label: -len(label))[0]

            for test_label in test_labels:
                app_label = get_containing_app(test_label)
                if app_label is not None:
                    app_module = import_module(app_label)
                    locations.append(os.path.dirname(app_module.__file__))
                else:
                    warnings.warn(
                        'No app found for test: {0}'.format(test_label))

        return locations
Example #34
0
def migration_hook(request):
    '''
    Pause migration at the migration named in @pytest.mark.migrate_from('0001-initial-migration')

    The migration_hook param will be a callable to then trigger the migration named in:
        @pytest.mark.migrate_from('0002-migrate-things')

    migration_hook also has an 'apps' attribute which is used to lookup models in the current migration state

    eg.
        MyModel = migration_hook.apps.get_model('myapp', 'MyModel')

    based on: https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/
    '''
    assert 'migrate_from' in request.keywords, 'must mark the migration to stop at with @pytest.mark.migrate_from()'
    assert len(request.keywords['migrate_from'].args) == 1, 'migrate_from mark expects 1 arg'
    assert not request.keywords['migrate_from'].kwargs, 'migrate_from mark takes no keywords'
    assert 'migrate_to' in request.keywords, 'must mark the migration to hook with @pytest.mark.migrate_to()'
    assert len(request.keywords['migrate_to'].args) == 1, 'migrate_to mark expects 1 arg'
    assert not request.keywords['migrate_to'].kwargs, 'migrate_to mark takes no keywords'

    app = apps.get_containing_app_config(request.module.__name__).name

    migrate_from = [(app, request.keywords['migrate_from'].args[0])]
    migrate_to = [(app, request.keywords['migrate_to'].args[0])]

    class migration_hook_result(object):

        def __init__(self, _from, _to):
            self._to = _to
            executor = MigrationExecutor(connection)
            self.apps = executor.loader.project_state(_from).apps

            # Reverse to the original migration
            executor.migrate(_from)

        def __call__(self):
            # Run the migration to test
            executor = MigrationExecutor(connection)
            executor.loader.build_graph()  # reload.
            executor.migrate(self._to)

            self.apps = executor.loader.project_state(self._to).apps

    yield migration_hook_result(migrate_from, migrate_to)
Example #35
0
    def setUp(self):
        super(TestModelsLoaderMixin, self).setUp()

        # If we made a fake 'models' module, add it to sys.modules.
        models_mod = self._tests_loader_models_mod

        if models_mod:
            sys.modules[models_mod.__name__] = models_mod

        self._models_loader_old_settings = settings.INSTALLED_APPS
        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + [
            self.tests_app,
        ]

        if apps:
            # Push the new set of installed apps, and begin registering
            # each of the models associated with the tests.
            apps.set_installed_apps(settings.INSTALLED_APPS)
            app_config = apps.get_containing_app_config(self.tests_app)

            if models_mod:
                app_label = app_config.label

                for key, value in six.iteritems(models_mod.__dict__):
                    if inspect.isclass(value) and issubclass(value, Model):
                        # The model was likely registered under another app,
                        # so we need to remove the old one and add the new
                        # one.
                        try:
                            del apps.all_models[value._meta.app_label][
                                value._meta.model_name]
                        except KeyError:
                            pass

                        value._meta.app_label = app_label
                        apps.register_model(app_label, value)

            call_command('migrate',
                         run_syncdb=True,
                         verbosity=0,
                         interactive=False)
        else:
            load_app(self.tests_app)
            call_command('syncdb', verbosity=0, interactive=False)
Example #36
0
    def _add_django_meta_and_register_model(cls, klass, attrs, name):
        # Create the class.
        module = attrs.get('__module__')
        if not module:
            return klass

        new_class = klass
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        if meta:
            meta.managed = False

        app_label = None

        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, 'app_label', None) is None:
            if app_config is None:
                if not abstract:
                    raise RuntimeError(
                        "Model class %s.%s doesn't declare an explicit "
                        "app_label and isn't in an application in "
                        "INSTALLED_APPS." % (module, name))

            else:
                app_label = app_config.label

        # Add _meta/Options attribute to the model
        new_class.add_to_class(
            '_meta', DjangoCassandraOptions(meta, app_label, cls=new_class))
        # Add manager to the model
        for manager_attr in _django_manager_attr_names:
            new_class.add_to_class(manager_attr, new_class.objects)
        # Register the model
        new_class._meta.apps.register_model(new_class._meta.app_label,
                                            new_class)
        return new_class
Example #37
0
    def _add_django_meta_and_register_model(cls, klass, attrs, name):
        # Create the class.
        module = attrs.get('__module__')
        if not module:
            return klass

        new_class = klass
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        if meta:
            meta.managed = False

        app_label = None

        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, 'app_label', None) is None:
            if app_config is None:
                if not abstract:
                    raise RuntimeError(
                        "Model class %s.%s doesn't declare an explicit "
                        "app_label and isn't in an application in "
                        "INSTALLED_APPS." % (module, name)
                    )

            else:
                app_label = app_config.label

        # Add _meta/Options attribute to the model
        new_class.add_to_class(
            '_meta', DjangoCassandraOptions(meta, app_label, cls=new_class))
        # Add manager to the model
        for manager_attr in _django_manager_attr_names:
            new_class.add_to_class(manager_attr, new_class.objects)
        # Register the model
        new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
        return new_class
Example #38
0
def get_containing_app_data(module):
    """Return app label and package string."""
    app_config = apps.get_containing_app_config(module)
    if not app_config:
        return None, None
    return app_config.label, app_config.module.__name__

    def with_metaclass(meta, *bases):
        """Create a base class with a metaclass."""
        class metaclass(meta):
            __call__ = type.__call__
            __init__ = type.__init__

            def __new__(cls, name, this_bases, d):
                if this_bases is None:
                    return type.__new__(cls, name, (), d)
                return meta(name, bases, d)

        return metaclass('temporary_class', None, {})
Example #39
0
    def get_tested_locations(self, test_labels):
        locations = []

        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        else:
            warnings.warn('No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        for test_label in test_labels:
            app_config = apps.get_containing_app_config(test_label)
            if app_config is not None:
                locations.append(os.path.dirname(app_config.module.__file__))
            else:
                warnings.warn('No app found for test: {0}'.format(test_label))

        return locations
Example #40
0
def get_containing_app_data(module):
    """Return app label and package string."""
    app_config = apps.get_containing_app_config(module)
    if not app_config:
        return None, None
    return app_config.label, app_config.module.__name__

    def with_metaclass(meta, *bases):
        """Create a base class with a metaclass."""
        class metaclass(meta):
            __call__ = type.__call__
            __init__ = type.__init__

            def __new__(cls, name, this_bases, d):
                if this_bases is None:
                    return type.__new__(cls, name, (), d)
                return meta(name, bases, d)

        return metaclass('temporary_class', None, {})
Example #41
0
    def setUp(self):
        super(TestModelsLoaderMixin, self).setUp()

        # If we made a fake 'models' module, add it to sys.modules.
        models_mod = self._tests_loader_models_mod

        if models_mod:
            sys.modules[models_mod.__name__] = models_mod

        self._models_loader_old_settings = settings.INSTALLED_APPS
        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + [
            self.tests_app,
        ]

        if apps:
            # Push the new set of installed apps, and begin registering
            # each of the models associated with the tests.
            apps.set_installed_apps(settings.INSTALLED_APPS)
            app_config = apps.get_containing_app_config(self.tests_app)

            if models_mod:
                app_label = app_config.label

                for key, value in six.iteritems(models_mod.__dict__):
                    if inspect.isclass(value) and issubclass(value, Model):
                        # The model was likely registered under another app,
                        # so we need to remove the old one and add the new
                        # one.
                        try:
                            del apps.all_models[value._meta.app_label][
                                value._meta.model_name]
                        except KeyError:
                            pass

                        value._meta.app_label = app_label
                        apps.register_model(app_label, value)

            call_command('migrate', run_syncdb=True, verbosity=0,
                         interactive=False)
        else:
            load_app(self.tests_app)
            call_command('syncdb', verbosity=0, interactive=False)
Example #42
0
    def get_tested_locations(self, test_labels):
        locations = []

        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        else:
            warnings.warn('No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        try:
            from django.apps import apps
            for test_label in test_labels:
                app_config = apps.get_containing_app_config(test_label)
                if app_config is not None:
                    locations.append(os.path.dirname(app_config.module.__file__))
                else:
                    warnings.warn('No app found for test: {0}'.format(test_label))
        except ImportError:
            # django 1.6
            from importlib import import_module

            def get_containing_app(object_name):
                candidates = []
                for app_label in settings.INSTALLED_APPS:
                    if object_name.startswith(app_label):
                        subpath = object_name[len(app_label):]
                        if subpath == '' or subpath[0] == '.':
                            candidates.append(app_label)
                if candidates:
                    return sorted(candidates, key=lambda label: -len(label))[0]

            for test_label in test_labels:
                app_label = get_containing_app(test_label)
                if app_label is not None:
                    app_module = import_module(app_label)
                    locations.append(os.path.dirname(app_module.__file__))
                else:
                    warnings.warn('No app found for test: {0}'.format(test_label))

        return locations
Example #43
0
    def get_tested_locations(self, test_labels):
        locations = []

        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        else:
            warnings.warn(
                'No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        for test_label in test_labels:
            app_config = apps.get_containing_app_config(test_label)
            if app_config is not None:
                locations.append(os.path.dirname(app_config.module.__file__))
            else:
                warnings.warn('No app found for test: {0}'.format(test_label))

        return locations
Example #44
0
    def get_tested_locations(self, test_labels):
        locations = []

        coverage = apps.get_app_config('django_jenkins').coverage
        if test_labels:
            pass
        elif hasattr(settings, 'PROJECT_APPS'):
            test_labels = settings.PROJECT_APPS
        elif coverage.coverage.source:
            warnings.warn("No PROJECT_APPS settings, using 'source' config from rcfile")
            locations = coverage.coverage.source
        else:
            warnings.warn('No PROJECT_APPS settings, coverage gathered over all apps')
            test_labels = settings.INSTALLED_APPS

        for test_label in test_labels:
            app_config = apps.get_containing_app_config(test_label)
            if app_config is not None:
                locations.append(app_config.path)
            else:
                warnings.warn('No app found for test: {0}'.format(test_label))

        return locations
Example #45
0
    def contribute_to_class(self, cls, name):
        setattr(cls, name, self)
        self.original_attrs = {}
        if self.meta:
            meta_attrs = self.meta.__dict__.copy()
            for name in self.meta.__dict__:
                if name.startswith('_'):
                    del meta_attrs[name]
            for attr_name in DEFAULT_NAMES:
                if attr_name in meta_attrs:
                    setattr(self,attr_name,meta_attrs.pop(attr_name))
                    self.original_attrs[attr_name] = getattr(self, attr_name)
                elif hasattr(self.meta, attr_name):
                    setattr(self, attr_name, getattr(self.meta, attr_name))
                    self.original_attrs[attr_name] = getattr(self, attr_name)

        del self.meta

        self.object_name = self.base_block.__name__

        if self.app_label is None:
            module = self.base_block.__module__
            self.app_config = apps.get_containing_app_config(module)
            self.app_label = self.app_config.label
Example #46
0
 def get_containing_app_data(module):
     """
     Return app label and package string
     """
     app_config = apps.get_containing_app_config(module)
     return app_config.label, app_config.module.__package__
 def app(self):
     return apps.get_containing_app_config(type(self).__module__).name
Example #48
0
def get_task_ref(flow_task):
    module = flow_task.flow_cls.__module__
    app_config = apps.get_containing_app_config(module)
    subpath = module.lstrip(app_config.module.__package__+'.')

    return "{}/{}.{}.{}".format(app_config.label, subpath, flow_task.flow_cls.__name__, flow_task.name)
Example #49
0
def default_access_fn(user, url_name, url_args=None, url_kwargs=None):  # noqa C901 too complex
    """
    Given a url_name and a user, this function tries to assess whether the
    user has the right to access the URL.
    The application instance of the view is fetched via the Django app
    registry.
    Once the permissions for the view are known, the access logic used
    by the dashboard decorator is evaluated

    This function might seem costly, but a simple comparison with DTT
    did not show any change in response time
    """
    if url_name is None:  # it's a heading
        return True

    # get view module string.
    try:
        url = reverse(url_name, args=url_args, kwargs=url_kwargs)
    except NoReverseMatch:
        # In Oscar 1.5 this exception was silently ignored which made debugging
        # very difficult. Now it is being logged and in future the exception will
        # be propagated.
        logger.exception('Invalid URL name {}'.format(url_name))
        return False

    view_module = resolve(url).func.__module__

    # We can't assume that the view has the same parent module as the app
    # config, as either the app config or view can be customised. So we first
    # look it up in the app registry using "get_containing_app_config", and if
    # it isn't found, then we walk up the package tree, looking for an
    # OscarDashboardConfig class, from which we get an app label, and use that
    # to look it up again in the app registry using "get_app_config".
    app_config_instance = apps.get_containing_app_config(view_module)
    if app_config_instance is None:
        try:
            app_config_class = get_app_config_class(view_module)
        except AppNotFoundError:
            raise ImproperlyConfigured(
                "Please provide an OscarDashboardConfig subclass in the apps "
                "module or set a custom access_fn")
        if hasattr(app_config_class, 'label'):
            app_label = app_config_class.label
        else:
            app_label = app_config_class.name.rpartition('.')[2]
        try:
            app_config_instance = apps.get_app_config(app_label)
        except LookupError:
            raise AppNotFoundError(
                "Couldn't find an app with the label %s" % app_label)
        if not isinstance(app_config_instance, OscarDashboardConfig):
            raise AppNotFoundError(
                "Couldn't find an Oscar Dashboard app with the label %s" % app_label)

    # handle name-spaced view names
    if ':' in url_name:
        view_name = url_name.split(':')[1]
    else:
        view_name = url_name
    permissions = app_config_instance.get_permissions(view_name)
    return check_permissions(user, permissions)
Example #50
0
def patched_new(cls, name, bases, attrs):
    "Patched version of __new__"

    super_new = super(ModelBase, cls).__new__

    # Also ensure initialization is only performed for subclasses of Model
    # (excluding Model class itself).
    parents = [b for b in bases if isinstance(b, ModelBase)]
    if not parents:
        return super_new(cls, name, bases, attrs)

    # Create the class.
    module = attrs.pop('__module__')
    new_class = super_new(cls, name, bases, {'__module__': module})
    attr_meta = attrs.pop('Meta', None)
    abstract = getattr(attr_meta, 'abstract', False)
    if not attr_meta:
        meta = getattr(new_class, 'Meta', None)
    else:
        meta = attr_meta
    base_meta = getattr(new_class, '_meta', None)

    # Look for an application configuration to attach the model to.
    app_config = apps.get_containing_app_config(module)

    if getattr(meta, 'app_label', None) is None:

        if app_config is None:
            # If the model is imported before the configuration for its
            # application is created (#21719), or isn't in an installed
            # application (#21680), use the legacy logic to figure out the
            # app_label by looking one level up from the package or module
            # named 'models'. If no such package or module exists, fall
            # back to looking one level up from the module this model is
            # defined in.

            # For 'django.contrib.sites.models', this would be 'sites'.
            # For 'geo.models.places' this would be 'geo'.

            if abstract:
                kwargs = {"app_label": None}
            else:
                msg = (
                    "Model class %s.%s doesn't declare an explicit app_label "
                    "and either isn't in an application in INSTALLED_APPS or "
                    "else was imported before its application was loaded. " %
                    (module, name))
                raise RuntimeError(msg)
    else:
        kwargs = {}

    new_class.add_to_class('_meta', Options(meta, **kwargs))
    if not abstract:
        new_class.add_to_class(
            'DoesNotExist',
            subclass_exception(
                str('DoesNotExist'),
                tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,),
                module,
                attached_to=new_class))
        new_class.add_to_class(
            'MultipleObjectsReturned',
            subclass_exception(
                str('MultipleObjectsReturned'),
                tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,),
                module,
                attached_to=new_class))
        if base_meta and not base_meta.abstract:
            # Non-abstract child classes inherit some attributes from their
            # non-abstract parent (unless an ABC comes before it in the
            # method resolution order).
            if not hasattr(meta, 'ordering'):
                new_class._meta.ordering = base_meta.ordering
            if not hasattr(meta, 'get_latest_by'):
                new_class._meta.get_latest_by = base_meta.get_latest_by

    is_proxy = new_class._meta.proxy

    # If the model is a proxy, ensure that the base class
    # hasn't been swapped out.
    if is_proxy and base_meta and base_meta.swapped:
        raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped))

    if getattr(new_class, '_default_manager', None):
        if not is_proxy:
            # Multi-table inheritance doesn't inherit default manager from
            # parents.
            new_class._default_manager = None
            new_class._base_manager = None
        else:
            # Proxy classes do inherit parent's default manager, if none is
            # set explicitly.
            new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
            new_class._base_manager = new_class._base_manager._copy_to_model(new_class)

    # Add all attributes to the class.
    for obj_name, obj in attrs.items():
        new_class.add_to_class(obj_name, obj)

    # All the fields of any type declared on this model
    new_fields = (
        new_class._meta.local_fields +
        new_class._meta.local_many_to_many +
        new_class._meta.virtual_fields
    )
    field_names = set(f.name for f in new_fields)

    # Basic setup for proxy models.
    if is_proxy:
        base = None
        for parent in [kls for kls in parents if hasattr(kls, '_meta')]:
            if parent._meta.abstract:
                if parent._meta.fields:
                    raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name)
                else:
                    continue
            #if base is not None:                              # patch
            while parent._meta.proxy:                          # patch
                parent = parent._meta.proxy_for_model          # patch
            if base is not None and base is not parent:        # patch
                raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
            else:
                base = parent
        if base is None:
            raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
        new_class._meta.setup_proxy(base)
        new_class._meta.concrete_model = base._meta.concrete_model
    else:
        new_class._meta.concrete_model = new_class

    # Collect the parent links for multi-table inheritance.
    parent_links = {}
    for base in reversed([new_class] + parents):
        # Conceptually equivalent to `if base is Model`.
        if not hasattr(base, '_meta'):
            continue
        # Skip concrete parent classes.
        if base != new_class and not base._meta.abstract:
            continue
        # Locate OneToOneField instances.
        for field in base._meta.local_fields:
            if isinstance(field, OneToOneField):
                parent_links[field.rel.to] = field

    # Do the appropriate setup for any model parents.
    for base in parents:
        original_base = base
        if not hasattr(base, '_meta'):
            # Things without _meta aren't functional models, so they're
            # uninteresting parents.
            continue

        parent_fields = base._meta.local_fields + base._meta.local_many_to_many
        # Check for clashes between locally declared fields and those
        # on the base classes (we cannot handle shadowed fields at the
        # moment).
        for field in parent_fields:
            if field.name in field_names:
                raise FieldError(
                    'Local field %r in class %r clashes '
                    'with field of similar name from '
                    'base class %r' % (field.name, name, base.__name__)
                )
        if not base._meta.abstract:
            # Concrete classes...
            base = base._meta.concrete_model
            if base in parent_links:
                field = parent_links[base]
            elif not is_proxy:
                attr_name = '%s_ptr' % base._meta.model_name
                field = OneToOneField(base, name=attr_name,
                        auto_created=True, parent_link=True)
                # Only add the ptr field if it's not already present;
                # e.g. migrations will already have it specified
                if not hasattr(new_class, attr_name):
                    new_class.add_to_class(attr_name, field)
            else:
                field = None
            new_class._meta.parents[base] = field
        else:
            # .. and abstract ones.
            for field in parent_fields:
                new_class.add_to_class(field.name, copy.deepcopy(field))

            # Pass any non-abstract parent classes onto child.
            new_class._meta.parents.update(base._meta.parents)

        # Inherit managers from the abstract base classes.
        new_class.copy_managers(base._meta.abstract_managers)

        # Proxy models inherit the non-abstract managers from their base,
        # unless they have redefined any of them.
        if is_proxy:
            new_class.copy_managers(original_base._meta.concrete_managers)

        # Inherit virtual fields (like GenericForeignKey) from the parent
        # class
        for field in base._meta.virtual_fields:
            if base._meta.abstract and field.name in field_names:
                raise FieldError(
                    'Local field %r in class %r clashes '
                    'with field of similar name from '
                    'abstract base class %r' % (field.name, name, base.__name__)
                )
            new_class.add_to_class(field.name, copy.deepcopy(field))

    if abstract:
        # Abstract base models can't be instantiated and don't appear in
        # the list of models for an app. We do the final setup for them a
        # little differently from normal models.
        attr_meta.abstract = False
        new_class.Meta = attr_meta
        return new_class

    new_class._prepare()
    new_class._meta.apps.register_model(new_class._meta.app_label, new_class)

    return new_class
Example #51
0
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__

        # six.with_metaclass() inserts an extra class called 'NewBase' in the
        # inheritance tree: Model -> NewBase -> object. But the initialization
        # should be executed only once for a given model class.

        # attrs will never be empty for classes declared in the standard way
        # (ie. with the `class` keyword). This is quite robust.
        if name == "NewBase" and attrs == {}:
            return super_new(cls, name, bases, attrs)

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [
            b for b in bases if isinstance(b, ModelBase) and not (b.__name__ == "NewBase" and b.__mro__ == (b, object))
        ]
        if not parents:
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop("__module__")
        new_class = super_new(cls, name, bases, {"__module__": module})
        attr_meta = attrs.pop("Meta", None)
        abstract = getattr(attr_meta, "abstract", False)
        if not attr_meta:
            meta = getattr(new_class, "Meta", None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, "_meta", None)

        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, "app_label", None) is None:

            if app_config is None:
                # If the model is imported before the configuration for its
                # application is created (#21719), or isn't in an installed
                # application (#21680), use the legacy logic to figure out the
                # app_label by looking one level up from the package or module
                # named 'models'. If no such package or module exists, fall
                # back to looking one level up from the module this model is
                # defined in.

                # For 'django.contrib.sites.models', this would be 'sites'.
                # For 'geo.models.places' this would be 'geo'.

                msg = (
                    "Model class %s.%s doesn't declare an explicit app_label "
                    "and either isn't in an application in INSTALLED_APPS or "
                    "else was imported before its application was loaded. " % (module, name)
                )
                if abstract:
                    msg += "Its app_label will be set to None in Django 1.9."
                else:
                    msg += "This will no longer be supported in Django 1.9."
                warnings.warn(msg, PendingDeprecationWarning, stacklevel=2)

                model_module = sys.modules[new_class.__module__]
                package_components = model_module.__name__.split(".")
                package_components.reverse()  # find the last occurrence of 'models'
                try:
                    app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
                except ValueError:
                    app_label_index = 1
                kwargs = {"app_label": package_components[app_label_index]}

            else:
                kwargs = {"app_label": app_config.label}

        else:
            kwargs = {}

        new_class.add_to_class("_meta", Options(meta, **kwargs))
        if not abstract:
            new_class.add_to_class(
                "DoesNotExist",
                subclass_exception(
                    str("DoesNotExist"),
                    tuple(x.DoesNotExist for x in parents if hasattr(x, "_meta") and not x._meta.abstract)
                    or (ObjectDoesNotExist,),
                    module,
                    attached_to=new_class,
                ),
            )
            new_class.add_to_class(
                "MultipleObjectsReturned",
                subclass_exception(
                    str("MultipleObjectsReturned"),
                    tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, "_meta") and not x._meta.abstract)
                    or (MultipleObjectsReturned,),
                    module,
                    attached_to=new_class,
                ),
            )
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, "ordering"):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, "get_latest_by"):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped))

        if getattr(new_class, "_default_manager", None):
            if not is_proxy:
                # Multi-table inheritance doesn't inherit default manager from
                # parents.
                new_class._default_manager = None
                new_class._base_manager = None
            else:
                # Proxy classes do inherit parent's default manager, if none is
                # set explicitly.
                new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
                new_class._base_manager = new_class._base_manager._copy_to_model(new_class)

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        # All the fields of any type declared on this model
        new_fields = new_class._meta.local_fields + new_class._meta.local_many_to_many + new_class._meta.virtual_fields
        field_names = set(f.name for f in new_fields)

        # Basic setup for proxy models.
        if is_proxy:
            base = None
            for parent in [kls for kls in parents if hasattr(kls, "_meta")]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError(
                            "Abstract base class containing model fields not permitted for proxy model '%s'." % name
                        )
                    else:
                        continue
                if base is not None:
                    raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
                else:
                    base = parent
            if base is None:
                raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
            if new_class._meta.local_fields or new_class._meta.local_many_to_many:
                raise FieldError("Proxy model '%s' contains model fields." % name)
            new_class._meta.setup_proxy(base)
            new_class._meta.concrete_model = base._meta.concrete_model
        else:
            new_class._meta.concrete_model = new_class

        # Collect the parent links for multi-table inheritance.
        parent_links = {}
        for base in reversed([new_class] + parents):
            # Conceptually equivalent to `if base is Model`.
            if not hasattr(base, "_meta"):
                continue
            # Skip concrete parent classes.
            if base != new_class and not base._meta.abstract:
                continue
            # Locate OneToOneField instances.
            for field in base._meta.local_fields:
                if isinstance(field, OneToOneField):
                    parent_links[field.rel.to] = field

        # Do the appropriate setup for any model parents.
        for base in parents:
            original_base = base
            if not hasattr(base, "_meta"):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError(
                        "Local field %r in class %r clashes "
                        "with field of similar name from "
                        "base class %r" % (field.name, name, base.__name__)
                    )
            if not base._meta.abstract:
                # Concrete classes...
                base = base._meta.concrete_model
                if base in parent_links:
                    field = parent_links[base]
                elif not is_proxy:
                    attr_name = "%s_ptr" % base._meta.model_name
                    field = OneToOneField(base, name=attr_name, auto_created=True, parent_link=True)
                    new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Proxy models inherit the non-abstract managers from their base,
            # unless they have redefined any of them.
            if is_proxy:
                new_class.copy_managers(original_base._meta.concrete_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError(
                        "Local field %r in class %r clashes "
                        "with field of similar name from "
                        "abstract base class %r" % (field.name, name, base.__name__)
                    )
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
        return new_class
Example #52
0
 def app_config(self):
     if not self._app_config:
         self._app_config = apps.get_containing_app_config(self.model.__module__)
     return self._app_config
Example #53
0
 def namespace(self):
     module = "{}.{}".format(self.flow_cls.__module__, self.flow_cls.__name__)
     app_config = apps.get_containing_app_config(module)
     subpath = module.lstrip(app_config.module.__package__+'.flows.')
     return "{}/{}".format(app_config.label, subpath)
def get_app_label(module):
    app_config = apps.get_containing_app_config(module)
    return app_config.label
Example #55
0
    def __new__(cls, name, bases, attrs):
        new_class = super(BrushfireModelBase, cls).__new__(cls, name, bases, attrs)
        
        parents = [b for b in bases if isinstance(b, BrushfireModelBase)]

        module = attrs.pop('__module__')
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
            
        app_config = apps.get_containing_app_config(module)
        setattr(new_class, 'objects', BrushfireManager(new_class))
        
        if getattr(meta, 'app_label', None):
            label = meta.app_label
        elif app_config:
            label = app_config.label
        else:
            label = '__NONE__'
            
        new_class.add_to_class('_meta', Options(meta, 
                **{'app_label':label}))
            
        new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    str('DoesNotExist'),
                    (ObjectDoesNotExist,),
                    module,
                    attached_to=new_class))
        new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    str('MultipleObjectsReturned'),
                    (MultipleObjectsReturned,),
                    module,
                    attached_to=new_class))

        if new_class._meta.proxy:
            raise BrushfireException, "BrushfireModels proxies not allowed."
                
        # add attributes to class
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)
                
        new_fields = chain(
                new_class._meta.local_fields,
                new_class._meta.local_many_to_many,
                new_class._meta.virtual_fields
        )
        field_names =  {f.name for f in new_fields}
        
        new_class._meta.concrete_model = new_class
        
        # Do the appropriate setup for any model parents.
        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError(
                        'Local field %r in class %r clashes '
                        'with field of similar name from '
                        'base class %r' % (field.name, name, base.__name__)
                    )
            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError(
                        'Local field %r in class %r clashes '
                        'with field of similar name from '
                        'abstract base class %r' % (field.name, name, base.__name__)
                    )
                new_class.add_to_class(field.name, copy.deepcopy(field))

        # Keep this stuff last
        new_class._prepare()
        # ModelBase calls this, not sure what it does or if we need it here. Need to investigate further.
        #new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
        return new_class
Example #56
0
 def __init__(self, view):
     from django.apps import apps
     app = apps.get_containing_app_config(utils.qualified_name(view))
     super(ViewMeta, self).__init__(app, view.__name__)
     self.view = view