Commit 2333c966 authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #14007 -- Added model discovery in models module without the need to specify app_label.

Thanks mark@ and Aramgutang for work on the patch.
parent fba6c2ed
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ from django.db.models.query_utils import DeferredAttribute, deferred_class_facto
from django.db.models.deletion import Collector
from django.db.models.options import Options
from django.db.models import signals
from django.db.models.loading import register_models, get_model
from django.db.models.loading import register_models, get_model, MODELS_MODULE_NAME
from django.utils.translation import ugettext_lazy as _
from django.utils.functional import curry
from django.utils.encoding import force_str, force_text
@@ -86,10 +86,22 @@ class ModelBase(type):
        base_meta = getattr(new_class, '_meta', None)

        if getattr(meta, 'app_label', None) is None:
            # Figure out the app_label by looking one level up.
            # 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'.

            model_module = sys.modules[new_class.__module__]
            kwargs = {"app_label": model_module.__name__.split('.')[-2]}
            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 = {}

+4 −2
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ import os
__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
        'load_app', 'app_cache_ready')

MODELS_MODULE_NAME = 'models'


class UnavailableApp(Exception):
    pass
@@ -98,12 +100,12 @@ class AppCache(object):
        self.nesting_level += 1
        app_module = import_module(app_name)
        try:
            models = import_module('.models', app_name)
            models = import_module('.' + MODELS_MODULE_NAME, app_name)
        except ImportError:
            self.nesting_level -= 1
            # If the app doesn't have a models module, we can just ignore the
            # ImportError and return no models for it.
            if not module_has_submodule(app_module, 'models'):
            if not module_has_submodule(app_module, MODELS_MODULE_NAME):
                return None
            # But if the app does have a models module, we need to figure out
            # whether to suppress or propagate the error. If can_postpone is
+8 −3
Original line number Diff line number Diff line
@@ -24,12 +24,17 @@ Available ``Meta`` options

.. attribute:: Options.app_label

    If a model exists outside of the standard :file:`models.py` (for instance,
    if the app's models are in submodules of ``myapp.models``), the model must
    define which app it is part of::
    If a model exists outside of the standard locations (:file:`models.py` or
    a ``models`` package in an app), the model must define which app it is part
    of::

        app_label = 'myapp'

    .. versionadded:: 1.7

        ``app_label`` is no longer required for models that are defined
        in a ``models`` package within an app.

``db_table``
------------

+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ Minor features
* The :meth:`QuerySet.update_or_create()
  <django.db.models.query.QuerySet.update_or_create>` method was added.

* :attr:`~django.db.models.Options.app_label` is no longer required for models
  that are defined in a ``models`` package within an app.

Backwards incompatible changes in 1.7
=====================================

+0 −3
Original line number Diff line number Diff line
@@ -6,6 +6,3 @@ class Article(models.Model):
    sites = models.ManyToManyField(Site)
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField("model_package.Publication", null=True, blank=True,)

    class Meta:
        app_label = 'model_package'
Loading