Sometimes it makes sense to split up your Django models for a specific application across multiple files instead of having all of them in one models.py file. This allows for easier and simpler code organization and maintenance.
Splitting up your models in Django is fairly simple, although it requires a few extra steps. In our example, we’ll create two Django models, Foo and Bar, each defined in their own files within an app called myapp.
Let’s also assume that Bar has a ForeignKey to Foo.
Create a models Python module within the app. The application directory structure may look something like:
- /myapp
- /models
- __init__.py
- bar.py
- foo.py
- /models
Here are the contents of foo.py:
from django.db import models
class Foo( models.Model ):
foo_text = models.CharField()
class Meta:
app_label = 'myapp'
And bar.py:
from django.db import models
from myapp.models.foo import Foo
class Bar( models.Model ):
foo = models.ForeignKey( Foo )
bar_text = models.CharField()
class Meta:
app_label = 'myapp'
Notice the definition of the app_label property in the inner Meta classes for each model. This is very important to let Django’s syncdb command know that these split up model classes belong to the same application.
We’re not done yet. You’ll also need to explicitly import each model class in the model module’s __init__.py file:
from myapp.models.foo import Foo from myapp.models.bar import Bar
And that’s it. Run syncdb and you should be all set.
NOTE: One thing to note about ForeignKey relationships is that the import order in __init__.py is very important. Since Bar has a ForeignKey to Foo, Foo must be imported before Bar.
NOTE: If you are splitting up the contents of an existing models.py file, make sure to delete the original models.py file when you are done otherwise syncdb may get confused.
UPDATE November 28, 2009 @ 3:30PM) Pedro Costa pointed out an existing issue with Django (ticket #6961) and loading fixtures for split up models. One solution is to just put the fixtures under the new /models sub-dir since Django is already looking for them there. However, this may break once they do fix the bug in the Django code base. Or you could try Justin Lillly’s approach which was mentioned on his blog.
UPDATE November 29, 2009 @ 10:04AM) I was asked to illustrate how to use a ForeignKey between these models. I have modified my post to show an example of how to do that.
