1

I have a relatively large flat application that I'm working on. To maintain separation of concerns, I've split the model and view files into auth_models, dashboard_models, taxonomy_models and more. These have been placed in the folder structure as

APPNAME/
  app/
    models/ 
      __init__.py
      auth_models.py
      dashboard_models.py
      taxonomy_models.py
      ...
    views/
      __init__.py
      dashboard_views.py
      taxonomy_views.py
      ...

My app/models/__init__.py has the following:

from auth_models import *
from dashboard_models import *
from taxonomy_models import *

However, when I run ./manage.py sql app, I get no output whatsoever. No warnings, nothing at all.

The reason for this question is I'm implementing a database modification and migration in which South cannot handle several aspects. So I'm essentially starting over with a fresh schema and will later implement a data conversion script to migrate the existing dataset. To do this, I need the schema to create the model tables.

Jason
  • 11,263
  • 21
  • 87
  • 181
  • See this answer http://stackoverflow.com/a/1160735/302243. Django makes assumptions about your app name from the path in which the models live, so you're forced in this situation to add a `class Meta: app_label = 'app'` to every model in the `*_models` files. – Austin Phillips Aug 20 '13 at 00:06
  • @AustinPhillips, that was the solution. If you make an answer, I'll accept it. Thanks! – Jason Aug 20 '13 at 00:52

2 Answers2

3

See this answer.

Django makes assumptions about your app name from the path in which the models live, so you're forced in this situation to add an app label to every imported model like this:

class MyModel(Model):
    # Model fields
    class Meta:
        app_label = 'app'

Background:

As of this writing, Django has the following code to detect an app label for a model:

    if getattr(meta, 'app_label', None) is None:
        # Figure out the app_label by looking one level up.
        # For 'django.contrib.sites.models', this would be 'sites'.
        model_module = sys.modules[new_class.__module__]
        kwargs = {"app_label": model_module.__name__.split('.')[-2]}

From this, we see that it infers the app_label from the modules name, which may exist deep in the app hierarchy.

Community
  • 1
  • 1
Austin Phillips
  • 15,228
  • 2
  • 51
  • 50
2

If your auth_models.py contains a model class MyUserModel, you need to put the following in the __init__.py under app/models:

try:
    from .auth_models import MyUserModel
except ImportError as e:
    sys.stderr.write("Error: failed to import models module ({})".format(e))

P.S. Another suggestion would be to improve the style you name your files with. Since auth_models.py, dashboard_models.py and taxonomy_models.py are all under app/models you can simply truncate the _models.py ending. I.e. rename your files under /models:

auth_models.py -> auth.py
dashboard_models.py -> dashboard.py
taxonomy_models.py -> taxonomy.py

To import the Model classes as instructed above:

from .auth import MyUserModel
Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102
  • Yes, I do import the models, and may implement your renaming suggestion. I've edited my question to include the contents of the `__init__.py` file. – Jason Aug 19 '13 at 23:28
  • Did you add the `try .. except` part to except for `ImportError`? – Joseph Victor Zammit Aug 19 '13 at 23:30
  • Yes I did. There is no change in output. Can this be a result of using `import *` rather than specific model names? – Jason Aug 19 '13 at 23:33
  • Give it a try, because I'm out of ideas. In my experience `import *` is legal but a bad practice (doesn't aid readability and you're importing stuff you might not need at all). – Joseph Victor Zammit Aug 19 '13 at 23:35
  • By the way, if you manage to make it work, you should do `except ImportError, e` and handling the exception accordingly. We shouldn't `except` blindly as I did in my example; in fact I will update it. – Joseph Victor Zammit Aug 19 '13 at 23:38
  • Thanks for the help, but I'm not getting any SQL output at all via `manage.py sql app`, nor any warnings. You do have a point about using import *, but all the models within those files are used for the app. – Jason Aug 19 '13 at 23:41