Example #1
0
 def test_egg5(self):
     """Loading an app from an egg that has an import error in its models module raises that error"""
     egg_name = '%s/brokenapp.egg' % self.egg_dir
     sys.path.append(egg_name)
     with six.assertRaisesRegex(self, ImportError, 'modelz'):
         with app_cache._with_app('broken_app'):
             app_cache.get_app_config('omelet.app_no_models').models_module
Example #2
0
 def test_egg2(self):
     """Loading an app from an egg that has no models returns no models (and no error)"""
     egg_name = '%s/nomodelapp.egg' % self.egg_dir
     sys.path.append(egg_name)
     with self.settings(INSTALLED_APPS=['app_no_models']):
         models_module = app_cache.get_app_config('app_no_models').models_module
         self.assertIsNone(models_module)
Example #3
0
 def test_egg3(self):
     """Models module can be loaded from an app located under an egg's top-level package"""
     egg_name = '%s/omelet.egg' % self.egg_dir
     sys.path.append(egg_name)
     with self.settings(INSTALLED_APPS=['omelet.app_with_models']):
         models_module = app_cache.get_app_config('app_with_models').models_module
         self.assertIsNotNone(models_module)
Example #4
0
 def test_egg4(self):
     """Loading an app with no models from under the top-level egg package generates no error"""
     egg_name = '%s/omelet.egg' % self.egg_dir
     sys.path.append(egg_name)
     with self.settings(INSTALLED_APPS=['omelet.app_no_models']):
         models_module = app_cache.get_app_config('app_no_models').models_module
         self.assertIsNone(models_module)
Example #5
0
    def test_sql_all(self):
        app = app_cache.get_app_config("commands_sql").models_module
        output = sql_all(app, no_style(), connections[DEFAULT_DB_ALIAS])

        self.assertEqual(self.count_ddl(output, "CREATE TABLE"), 3)
        # PostgreSQL creates one additional index for CharField
        self.assertIn(self.count_ddl(output, "CREATE INDEX"), [3, 4])
Example #6
0
 def test_egg1(self):
     """Models module can be loaded from an app in an egg"""
     egg_name = '%s/modelapp.egg' % self.egg_dir
     sys.path.append(egg_name)
     with self.settings(INSTALLED_APPS=['app_with_models']):
         models_module = app_cache.get_app_config('app_with_models').models_module
         self.assertIsNotNone(models_module)
Example #7
0
 def test_sql_delete(self):
     app = app_cache.get_app_config("commands_sql").models_module
     output = sql_delete(app, no_style(), connections[DEFAULT_DB_ALIAS])
     drop_tables = [o for o in output if o.startswith("DROP TABLE")]
     self.assertEqual(len(drop_tables), 3)
     # Lower so that Oracle's upper case tbl names wont break
     sql = drop_tables[-1].lower()
     six.assertRegex(self, sql, r"^drop table .commands_sql_comment.*")
Example #8
0
    def app_index(self, request, app_label, extra_context=None):
        user = request.user
        app_name = app_cache.get_app_config(app_label).verbose_name
        has_module_perms = user.has_module_perms(app_label)
        if not has_module_perms:
            raise PermissionDenied
        app_dict = {}
        for model, model_admin in self._registry.items():
            if app_label == model._meta.app_label:
                perms = model_admin.get_model_perms(request)

                # Check whether user has any perm for this module.
                # If so, add the module to the model_list.
                if True in perms.values():
                    info = (app_label, model._meta.model_name)
                    model_dict = {
                        'name': capfirst(model._meta.verbose_name_plural),
                        'object_name': model._meta.object_name,
                        'perms': perms,
                    }
                    if perms.get('change'):
                        try:
                            model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=self.name)
                        except NoReverseMatch:
                            pass
                    if perms.get('add'):
                        try:
                            model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=self.name)
                        except NoReverseMatch:
                            pass
                    if app_dict:
                        app_dict['models'].append(model_dict),
                    else:
                        # First time around, now that we know there's
                        # something to display, add in the necessary meta
                        # information.
                        app_dict = {
                            'name': app_name,
                            'app_label': app_label,
                            'app_url': '',
                            'has_module_perms': has_module_perms,
                            'models': [model_dict],
                        }
        if not app_dict:
            raise Http404('The requested admin page does not exist.')
        # Sort the models alphabetically within each app.
        app_dict['models'].sort(key=lambda x: x['name'])
        context = dict(self.each_context(),
            title=_('%(app)s administration') % {'app': app_name},
            app_list=[app_dict],
            app_label=app_label,
        )
        context.update(extra_context or {})

        return TemplateResponse(request, self.app_index_template or [
            'admin/%s/app_index.html' % app_label,
            'admin/app_index.html'
        ], context, current_app=self.name)
Example #9
0
def get_comment_app():
    """
    Get the comment app (i.e. "django.contrib.comments") as defined in the settings
    """
    try:
        app_config = app_cache.get_app_config(get_comment_app_name().rpartition(".")[2])
    except LookupError:
        raise ImproperlyConfigured("The COMMENTS_APP (%r) "
                                   "must be in INSTALLED_APPS" % settings.COMMENTS_APP)
    return app_config.app_module
Example #10
0
    def test_suite_override(self):
        """
        Validate that you can define a custom suite when running tests with
        ``django.test.simple.DjangoTestSuiteRunner`` (which builds up a test
        suite using ``build_suite``).
        """

        from django.test.simple import build_suite
        app_config = app_cache.get_app_config("test_suite_override")
        suite = build_suite(app_config)
        self.assertEqual(suite.countTestCases(), 1)
Example #11
0
 def test_dynamic_load(self):
     """
     Makes a new model at runtime and ensures it goes into the right place.
     """
     old_models = app_cache.get_models(app_cache.get_app_config("app_cache").models_module)
     # Construct a new model in a new app cache
     body = {}
     new_app_cache = AppCache()
     meta_contents = {
         'app_label': "app_cache",
         'app_cache': new_app_cache,
     }
     meta = type("Meta", tuple(), 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(
         old_models,
         app_cache.get_models(app_cache.get_app_config("app_cache").models_module),
     )
     self.assertEqual(new_app_cache.get_model("app_cache", "SouthPonies"), temp_model)
Example #12
0
    def test_invalid_models(self):
        module = app_cache.get_app_config("invalid_models").models_module
        get_validation_errors(self.stdout, module)

        self.stdout.seek(0)
        error_log = self.stdout.read()
        actual = error_log.split('\n')
        expected = module.model_errors.split('\n')

        unexpected = [err for err in actual if err not in expected]
        missing = [err for err in expected if err not in actual]
        self.assertFalse(unexpected, "Unexpected Errors: " + '\n'.join(unexpected))
        self.assertFalse(missing, "Missing Errors: " + '\n'.join(missing))
Example #13
0
    def test_ticket_11936(self):
        # Regression for #11936 - loading.get_models should not return deferred
        # models by default.
        # Run a couple of defer queries so that app-cache must contain some
        # deferred classes. It might contain a lot more classes depending on
        # the order the tests are ran.
        list(Item.objects.defer("name"))
        list(Child.objects.defer("value"))
        klasses = set(
            map(
                attrgetter("__name__"),
                app_cache.get_models(app_cache.get_app_config("defer_regress").models_module)
            )
        )
        self.assertIn("Child", klasses)
        self.assertIn("Item", klasses)
        self.assertNotIn("Child_Deferred_value", klasses)
        self.assertNotIn("Item_Deferred_name", klasses)
        self.assertFalse(any(
            k._deferred for k in app_cache.get_models(app_cache.get_app_config("defer_regress").models_module)))

        klasses_with_deferred = set(
            map(
                attrgetter("__name__"),
                app_cache.get_models(
                    app_cache.get_app_config("defer_regress").models_module, include_deferred=True
                ),
            )
        )
        self.assertIn("Child", klasses_with_deferred)
        self.assertIn("Item", klasses_with_deferred)
        self.assertIn("Child_Deferred_value", klasses_with_deferred)
        self.assertIn("Item_Deferred_name", klasses_with_deferred)
        self.assertTrue(any(
            k._deferred for k in app_cache.get_models(
                app_cache.get_app_config("defer_regress").models_module, include_deferred=True))
        )
Example #14
0
    def path(self):
        migrations_package_name = MigrationLoader.migrations_module(self.migration.app_label)
        # See if we can import the migrations module directly
        try:
            migrations_module = import_module(migrations_package_name)
            basedir = os.path.dirname(migrations_module.__file__)
        except ImportError:
            app_config = app_cache.get_app_config(self.migration.app_label)
            migrations_package_basename = migrations_package_name.split(".")[-1]

            # Alright, see if it's a direct submodule of the app
            if "%s.%s" % (app_config.name, migrations_package_basename) == migrations_package_name:
                basedir = os.path.join(app_config.path, migrations_package_basename)
            else:
                raise ImportError(
                    "Cannot open migrations module %s for app %s" % (migrations_package_name, self.migration.app_label)
                )
        return os.path.join(basedir, self.filename)
Example #15
0
    def build_suite(self, test_labels, extra_tests=None, **kwargs):
        suite = unittest.TestSuite()

        if test_labels:
            for label in test_labels:
                if '.' in label:
                    suite.addTest(build_test(label))
                else:
                    app_config = app_cache.get_app_config(label)
                    suite.addTest(build_suite(app_config))
        else:
            for app_config in app_cache.get_app_configs():
                suite.addTest(build_suite(app_config))

        if extra_tests:
            for test in extra_tests:
                suite.addTest(test)

        return runner.reorder_suite(suite, (unittest.TestCase,))
Example #16
0
 def ask_initial(self, app_label):
     "Should we create an initial migration for the app?"
     # If it was specified on the command line, definitely true
     if app_label in self.specified_apps:
         return True
     # Otherwise, we look to see if it has a migrations module
     # without any Python files in it, apart from __init__.py.
     # Apps from the new app template will have these; the python
     # file check will ensure we skip South ones.
     try:
         app_config = app_cache.get_app_config(app_label)
     except LookupError:         # It's a fake app.
         return self.defaults.get("ask_initial", False)
     migrations_import_path = "%s.migrations" % app_config.name
     try:
         migrations_module = importlib.import_module(migrations_import_path)
     except ImportError:
         return self.defaults.get("ask_initial", False)
     else:
         filenames = os.listdir(os.path.dirname(migrations_module.__file__))
         return not any(x.endswith(".py") for x in filenames if x != "__init__.py")
Example #17
0
 def handle(self, *app_labels, **options):
     from django.apps import app_cache
     if not app_labels:
         raise CommandError('Enter at least one appname.')
     # Populate models and don't use only_with_models_module=True when
     # calling get_app_config() to tell apart missing apps from apps
     # without a model module -- which can't be supported with the legacy
     # API since it passes the models module to handle_app().
     app_cache.populate_models()
     try:
         app_configs = [app_cache.get_app_config(app_label) for app_label in app_labels]
     except (LookupError, ImportError) as e:
         raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e)
     output = []
     for app_config in app_configs:
         if app_config.models_module is None:
             raise CommandError(
                 "AppCommand cannot handle app %r because it doesn't have "
                 "a models module." % app_config.label)
         app_output = self.handle_app(app_config.models_module, **options)
         if app_output:
             output.append(app_output)
     return '\n'.join(output)
Example #18
0
def custom_sql_for_model(model, style, connection):
    opts = model._meta
    app_dirs = []
    app_dir = app_cache.get_app_config(model._meta.app_label).path
    app_dirs.append(os.path.normpath(os.path.join(app_dir, 'sql')))

    # Deprecated location -- remove in Django 1.9
    old_app_dir = os.path.normpath(os.path.join(app_dir, 'models/sql'))
    if os.path.exists(old_app_dir):
        warnings.warn("Custom SQL location '<app_label>/models/sql' is "
                      "deprecated, use '<app_label>/sql' instead.",
                      PendingDeprecationWarning)
        app_dirs.append(old_app_dir)

    output = []

    # Post-creation SQL should come before any initial SQL data is loaded.
    # However, this should not be done for models that are unmanaged or
    # for fields that are part of a parent model (via model inheritance).
    if opts.managed:
        post_sql_fields = [f for f in opts.local_fields if hasattr(f, 'post_create_sql')]
        for f in post_sql_fields:
            output.extend(f.post_create_sql(style, model._meta.db_table))

    # Find custom SQL, if it's available.
    backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
    sql_files = []
    for app_dir in app_dirs:
        sql_files.append(os.path.join(app_dir, "%s.%s.sql" % (opts.model_name, backend_name)))
        sql_files.append(os.path.join(app_dir, "%s.sql" % opts.model_name))
    for sql_file in sql_files:
        if os.path.exists(sql_file):
            with codecs.open(sql_file, 'U', encoding=settings.FILE_CHARSET) as fp:
                # Some backends can't execute more than one SQL statement at a time,
                # so split into separate statements.
                output.extend(_split_statements(fp.read()))
    return output
Example #19
0
    def handle(self, *app_labels, **options):
        from django.apps import app_cache

        format = options.get('format')
        indent = options.get('indent')
        using = options.get('database')
        excludes = options.get('exclude')
        show_traceback = options.get('traceback')
        use_natural_keys = options.get('use_natural_keys')
        if use_natural_keys:
            warnings.warn("``--natural`` is deprecated; use ``--natural-foreign`` instead.",
                PendingDeprecationWarning)
        use_natural_foreign_keys = options.get('use_natural_foreign_keys') or use_natural_keys
        use_natural_primary_keys = options.get('use_natural_primary_keys')
        use_base_manager = options.get('use_base_manager')
        pks = options.get('primary_keys')

        if pks:
            primary_keys = pks.split(',')
        else:
            primary_keys = []

        excluded_apps = set()
        excluded_models = set()
        for exclude in excludes:
            if '.' in exclude:
                app_label, model_name = exclude.split('.', 1)
                model_obj = app_cache.get_model(app_label, model_name)
                if not model_obj:
                    raise CommandError('Unknown model in excludes: %s' % exclude)
                excluded_models.add(model_obj)
            else:
                try:
                    app_obj = app_cache.get_app_config(exclude).models_module
                    if app_obj is not None:
                        excluded_apps.add(app_obj)
                except LookupError:
                    raise CommandError('Unknown app in excludes: %s' % exclude)

        if len(app_labels) == 0:
            if primary_keys:
                raise CommandError("You can only use --pks option with one model")
            app_list = OrderedDict((app_config.models_module, None)
                for app_config in app_cache.get_app_configs(only_with_models_module=True)
                if app_config.models_module not in excluded_apps)
        else:
            if len(app_labels) > 1 and primary_keys:
                raise CommandError("You can only use --pks option with one model")
            app_list = OrderedDict()
            for label in app_labels:
                try:
                    app_label, model_label = label.split('.')
                    try:
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app is None or app in excluded_apps:
                        continue
                    model = app_cache.get_model(app_label, model_label)
                    if model is None:
                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))

                    if app in app_list.keys():
                        if app_list[app] and model not in app_list[app]:
                            app_list[app].append(model)
                    else:
                        app_list[app] = [model]
                except ValueError:
                    if primary_keys:
                        raise CommandError("You can only use --pks option with one model")
                    # This is just an app - no model qualifier
                    app_label = label
                    try:
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app is None or app in excluded_apps:
                        continue
                    app_list[app] = None

        # Check that the serialization format exists; this is a shortcut to
        # avoid collating all the objects and _then_ failing.
        if format not in serializers.get_public_serializer_formats():
            try:
                serializers.get_serializer(format)
            except serializers.SerializerDoesNotExist:
                pass

            raise CommandError("Unknown serialization format: %s" % format)

        def get_objects():
            # Collate the objects to be serialized.
            for model in sort_dependencies(app_list.items()):
                if model in excluded_models:
                    continue
                if not model._meta.proxy and router.allow_migrate(using, model):
                    if use_base_manager:
                        objects = model._base_manager
                    else:
                        objects = model._default_manager

                    queryset = objects.using(using).order_by(model._meta.pk.name)
                    if primary_keys:
                        queryset = queryset.filter(pk__in=primary_keys)
                    for obj in queryset.iterator():
                        yield obj

        try:
            self.stdout.ending = None
            serializers.serialize(format, get_objects(), indent=indent,
                    use_natural_foreign_keys=use_natural_foreign_keys,
                    use_natural_primary_keys=use_natural_primary_keys,
                    stream=self.stdout)
        except Exception as e:
            if show_traceback:
                raise
            raise CommandError("Unable to serialize database: %s" % e)
Example #20
0
 def test_sql_destroy_indexes(self):
     app = app_cache.get_app_config("commands_sql").models_module
     output = sql_destroy_indexes(app, no_style(), connections[DEFAULT_DB_ALIAS])
     # PostgreSQL creates one additional index for CharField
     self.assertIn(self.count_ddl(output, "DROP INDEX"), [3, 4])
Example #21
0
    def index(self, request, extra_context=None):
        """
        Displays the main admin index page, which lists all of the installed
        apps that have been registered in this site.
        """
        app_dict = {}
        user = request.user
        for model, model_admin in self._registry.items():
            app_label = model._meta.app_label
            has_module_perms = user.has_module_perms(app_label)

            if has_module_perms:
                perms = model_admin.get_model_perms(request)

                # Check whether user has any perm for this module.
                # If so, add the module to the model_list.
                if True in perms.values():
                    info = (app_label, model._meta.model_name)
                    model_dict = {
                        'name': capfirst(model._meta.verbose_name_plural),
                        'object_name': model._meta.object_name,
                        'perms': perms,
                    }
                    if perms.get('change', False):
                        try:
                            model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=self.name)
                        except NoReverseMatch:
                            pass
                    if perms.get('add', False):
                        try:
                            model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=self.name)
                        except NoReverseMatch:
                            pass
                    if app_label in app_dict:
                        app_dict[app_label]['models'].append(model_dict)
                    else:
                        app_dict[app_label] = {
                            'name': app_cache.get_app_config(app_label).verbose_name,
                            'app_label': app_label,
                            'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name),
                            'has_module_perms': has_module_perms,
                            'models': [model_dict],
                        }

        # Sort the apps alphabetically.
        app_list = list(six.itervalues(app_dict))
        app_list.sort(key=lambda x: x['name'].lower())

        # Sort the models alphabetically within each app.
        for app in app_list:
            app['models'].sort(key=lambda x: x['name'])

        context = dict(
            self.each_context(),
            title=self.index_title,
            app_list=app_list,
        )
        context.update(extra_context or {})
        return TemplateResponse(request, self.index_template or
                                'admin/index.html', context,
                                current_app=self.name)
Example #22
0
 def test_router_honored(self):
     app = app_cache.get_app_config("commands_sql").models_module
     for sql_command in (sql_all, sql_create, sql_delete, sql_indexes, sql_destroy_indexes):
         output = sql_command(app, no_style(), connections[DEFAULT_DB_ALIAS])
         self.assertEqual(len(output), 0, "%s command is not honoring routers" % sql_command.__name__)
Example #23
0
def build_test(label):
    """
    Construct a test case with the specified label. Label should be of the
    form app_label.TestClass or app_label.TestClass.test_method. Returns an
    instantiated test or test suite corresponding to the label provided.
    """
    parts = label.split('.')
    if len(parts) < 2 or len(parts) > 3:
        raise ValueError("Test label '%s' should be of the form app.TestCase "
                         "or app.TestCase.test_method" % label)

    app_config = app_cache.get_app_config(parts[0])
    models_module = app_config.models_module
    tests_module = get_tests(app_config)

    test_modules = []
    if models_module:
        test_modules.append(models_module)
    if tests_module:
        test_modules.append(tests_module)

    TestClass = None
    for module in test_modules:
        TestClass = getattr(models_module, parts[1], None)
        if TestClass is not None:
            break

    try:
        if issubclass(TestClass, (unittest.TestCase, real_unittest.TestCase)):
            if len(parts) == 2:  # label is app.TestClass
                try:
                    return unittest.TestLoader().loadTestsFromTestCase(
                        TestClass)
                except TypeError:
                    raise ValueError(
                        "Test label '%s' does not refer to a test class"
                        % label)
            else:  # label is app.TestClass.test_method
                return TestClass(parts[2])
    except TypeError:
        # TestClass isn't a TestClass - it must be a method or normal class
        pass

    #
    # If there isn't a TestCase, look for a doctest that matches
    #
    tests = []
    for module in test_modules:
        try:
            doctests = make_doctest(module)
            # Now iterate over the suite, looking for doctests whose name
            # matches the pattern that was given
            for test in doctests:
                if test._dt_test.name in (
                        '%s.%s' % (module.__name__, '.'.join(parts[1:])),
                        '%s.__test__.%s' % (
                            module.__name__, '.'.join(parts[1:]))):
                    tests.append(test)
        except ValueError:
            # No doctests found.
            pass

    # If no tests were found, then we were given a bad test label.
    if not tests:
        raise ValueError("Test label '%s' does not refer to a test" % label)

    # Construct a suite out of the tests that matched.
    return unittest.TestSuite(tests)
Example #24
0
 def test_username_non_unique(self):
     "A non-unique USERNAME_FIELD should raise a model validation error."
     new_io = StringIO()
     get_validation_errors(new_io, app_cache.get_app_config('auth').models_module)
     self.assertIn("The USERNAME_FIELD must be unique. Add unique=True to the field parameters.", new_io.getvalue())
Example #25
0
 def test_username_not_in_required_fields(self):
     "USERNAME_FIELD should not appear in REQUIRED_FIELDS."
     new_io = StringIO()
     get_validation_errors(new_io, app_cache.get_app_config('auth').models_module)
     self.assertIn("The field named as the USERNAME_FIELD should not be included in REQUIRED_FIELDS on a swappable User model.", new_io.getvalue())
Example #26
0
 def test_required_fields_is_list(self):
     "REQUIRED_FIELDS should be a list."
     new_io = StringIO()
     get_validation_errors(new_io, app_cache.get_app_config('auth').models_module)
     self.assertIn("The REQUIRED_FIELDS must be a list or tuple.", new_io.getvalue())
Example #27
0
    def handle(self, *app_labels, **options):

        self.verbosity = int(options.get('verbosity'))
        self.interactive = options.get('interactive')
        self.dry_run = options.get('dry_run', False)
        self.merge = options.get('merge', False)

        # Make sure the app they asked for exists
        app_labels = set(app_labels)
        bad_app_labels = set()
        for app_label in app_labels:
            try:
                app_cache.get_app_config(app_label)
            except LookupError:
                bad_app_labels.add(app_label)
        if bad_app_labels:
            for app_label in bad_app_labels:
                self.stderr.write("App '%s' could not be found. Is it in INSTALLED_APPS?" % app_label)
            sys.exit(2)

        # Load the current graph state. Takes a connection, but it's not used
        # (makemigrations doesn't look at the database state).
        loader = MigrationLoader(connections[DEFAULT_DB_ALIAS])

        # Before anything else, see if there's conflicting apps and drop out
        # hard if there are any and they don't want to merge
        conflicts = loader.detect_conflicts()
        if conflicts and not self.merge:
            name_str = "; ".join(
                "%s in %s" % (", ".join(names), app)
                for app, names in conflicts.items()
            )
            raise CommandError("Conflicting migrations detected (%s).\nTo fix them run 'python manage.py makemigrations --merge'" % name_str)

        # If they want to merge and there's nothing to merge, then politely exit
        if self.merge and not conflicts:
            self.stdout.write("No conflicts detected to merge.")
            return

        # If they want to merge and there is something to merge, then
        # divert into the merge code
        if self.merge and conflicts:
            return self.handle_merge(loader, conflicts)

        # Detect changes
        autodetector = MigrationAutodetector(
            loader.graph.project_state(),
            ProjectState.from_app_cache(app_cache),
            InteractiveMigrationQuestioner(specified_apps=app_labels),
        )
        changes = autodetector.changes(graph=loader.graph, trim_to_apps=app_labels or None)

        # No changes? Tell them.
        if not changes and self.verbosity >= 1:
            if len(app_labels) == 1:
                self.stdout.write("No changes detected in app '%s'" % app_labels.pop())
            elif len(app_labels) > 1:
                self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels)))
            else:
                self.stdout.write("No changes detected")
            return

        directory_created = {}
        for app_label, app_migrations in changes.items():
            if self.verbosity >= 1:
                self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app_label) + "\n")
            for migration in app_migrations:
                # Describe the migration
                writer = MigrationWriter(migration)
                if self.verbosity >= 1:
                    self.stdout.write("  %s:\n" % (self.style.MIGRATE_LABEL(writer.filename),))
                    for operation in migration.operations:
                        self.stdout.write("    - %s\n" % operation.describe())
                # Write it
                if not self.dry_run:
                    migrations_directory = os.path.dirname(writer.path)
                    if not directory_created.get(app_label, False):
                        if not os.path.isdir(migrations_directory):
                            os.mkdir(migrations_directory)
                        init_path = os.path.join(migrations_directory, "__init__.py")
                        if not os.path.isfile(init_path):
                            open(init_path, "w").close()
                        # We just do this once per app
                        directory_created[app_label] = True
                    migration_string = writer.as_string()
                    with open(writer.path, "wb") as fh:
                        fh.write(migration_string)
Example #28
0
 def test_no_models(self):
     """Test that it's possible to load an app with no models.py file."""
     app_config = app_cache.get_app_config('no_models')
     self.assertIsNone(app_config.models_module)
Example #29
0
 def migrations_module(cls, app_label):
     if app_label in settings.MIGRATION_MODULES:
         return settings.MIGRATION_MODULES[app_label]
     else:
         return "%s.migrations" % app_cache.get_app_config(app_label).name
Example #30
0
    def get_context_data(self, **kwargs):
        # Get the model class.
        try:
            app_cache.get_app_config(self.kwargs['app_label'])
        except LookupError:
            raise Http404(_("App %(app_label)r not found") % self.kwargs)
        model = app_cache.get_model(self.kwargs['app_label'], self.kwargs['model_name'])
        if model is None:
            raise Http404(_("Model %(model_name)r not found in app %(app_label)r") % self.kwargs)

        opts = model._meta

        # Gather fields/field descriptions.
        fields = []
        for field in opts.fields:
            # ForeignKey is a special case since the field will actually be a
            # descriptor that returns the other object
            if isinstance(field, models.ForeignKey):
                data_type = field.rel.to.__name__
                app_label = field.rel.to._meta.app_label
                verbose = utils.parse_rst(
                    (_("the related `%(app_label)s.%(data_type)s` object") % {
                        'app_label': app_label, 'data_type': data_type,
                    }),
                    'model',
                    _('model:') + data_type,
                )
            else:
                data_type = get_readable_field_data_type(field)
                verbose = field.verbose_name
            fields.append({
                'name': field.name,
                'data_type': data_type,
                'verbose': verbose,
                'help_text': field.help_text,
            })

        # Gather many-to-many fields.
        for field in opts.many_to_many:
            data_type = field.rel.to.__name__
            app_label = field.rel.to._meta.app_label
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {'app_label': app_label, 'object_name': data_type}
            fields.append({
                'name': "%s.all" % field.name,
                "data_type": 'List',
                'verbose': utils.parse_rst(_("all %s") % verbose, 'model', _('model:') + opts.model_name),
            })
            fields.append({
                'name': "%s.count" % field.name,
                'data_type': 'Integer',
                'verbose': utils.parse_rst(_("number of %s") % verbose, 'model', _('model:') + opts.model_name),
            })

        # Gather model methods.
        for func_name, func in model.__dict__.items():
            if (inspect.isfunction(func) and len(inspect.getargspec(func)[0]) == 1):
                try:
                    for exclude in MODEL_METHODS_EXCLUDE:
                        if func_name.startswith(exclude):
                            raise StopIteration
                except StopIteration:
                    continue
                verbose = func.__doc__
                if verbose:
                    verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.model_name)
                fields.append({
                    'name': func_name,
                    'data_type': get_return_data_type(func_name),
                    'verbose': verbose,
                })

        # Gather related objects
        for rel in opts.get_all_related_objects() + opts.get_all_related_many_to_many_objects():
            verbose = _("related `%(app_label)s.%(object_name)s` objects") % {'app_label': rel.opts.app_label, 'object_name': rel.opts.object_name}
            accessor = rel.get_accessor_name()
            fields.append({
                'name': "%s.all" % accessor,
                'data_type': 'List',
                'verbose': utils.parse_rst(_("all %s") % verbose, 'model', _('model:') + opts.model_name),
            })
            fields.append({
                'name': "%s.count" % accessor,
                'data_type': 'Integer',
                'verbose': utils.parse_rst(_("number of %s") % verbose, 'model', _('model:') + opts.model_name),
            })
        kwargs.update({
            'name': '%s.%s' % (opts.app_label, opts.object_name),
            # Translators: %s is an object type name
            'summary': _("Attributes on %s objects") % opts.object_name,
            'description': model.__doc__,
            'fields': fields,
        })
        return super(ModelDetailView, self).get_context_data(**kwargs)