categorizing models in own files instead of models.py

My models.py is spanning 2000 lines with scores of model classes - is there some standard convention to keep each class in separate model files ? And how do we import the whole 20+ models in the models.py file ?

Yes there is a way, You can create a separate file like separate_models.py that have models A, B, C. Then in your models.py just import it and run migrations command it will be migrated and work like rest of your models defined in models.py.

Note: Just Import your separate_models in models.py and run migrations command, Also in your admin.py you can register these models same as you do with models.py models.

from .separate_models import (
    A, B, C, etc...
)

I don’t see why you shouldn’t be able to do it, even though I didn’t have to do it myself. It must be no different to import a model from another application for use in your own model. In the same folder as your models.py, create your files modelA.py modelB.py
then use them in models.py, that should do the trick.

See CookBookSplitModelsToFiles – Django

Yes, the reference is old, and their note regarding the Meta class no longer applies, but this is a standard pattern for creating a module for models instead of a single file.

(Side note: Please do your developers a favor and do not make this 1 model per file. Python is not Java. At a minimum allow for some common groupings of directly related models in a common file. Your developers will thank you for it.)

Thank you for your feedback, @KenWhitesell . I understand that my proposal to split models into multiple files might seem counterintuitive, and I acknowledge your concerns about logically grouping models. However, I’d like to understand better why this approach could be problematic. In my understanding, Django does not restrict us to one model per file - it’s entirely feasible to distribute models across multiple files for clarity and organization, especially in larger projects. For instance, in a large project, we might have separate files such as order_models.py, customer_models.py, etc., grouping related models logically, while then importing them into models.py for centralized management. This method seems to be a common practice for managing complex projects, improving readability and maintainability. That said, I’m open to your insights and experiences on why this approach might not be ideal, or how it could be improved."

Project structure example:

myapp/
    __init__.py
    models/
        __init__.py
        user.py
        product.py
        order.py
        ...

myapp/models/user.py:

from django.db import models

class User(models.Model):
    # Define User model fields and behavior here
    ...

myapp/models/product.py:

from django.db import models

class Product(models.Model):
    # Define Product model fields and behavior here
    ...

In myapp/models/order.py:

pythonCopy code

from django.db import models

class Order(models.Model):
    # Define Order model fields and behavior here
    ...

And finally, in myapp/models/__init__.py:

from .user import User
from .product import Product
from .order import Order
# Import other models here as needed
...

With this structure, each model is placed in its own file for better organization and clarity, especially in large projects. Each model is then imported into the __init__.py file for centralized management and simplified importing into other parts of the application. This approach allows for maintaining smaller, more manageable model files while offering flexibility for future project growth.

My experience has been that “clarity and organization” - especially in larger projects, is not enhanced by dramatically increasing the number of files involved. In fact, I have found the exact opposite to be true.

We don’t even begin to think about splitting apart our models.py files until they’re at least 2000 lines, and will let them get to about 2500 before taking action. (And, in some cases - typically when external databases are involved, that “action” ends up being “do nothing” because we recognize there’s no benefit in those cases by splitting up the models.)

And, in those cases where we do choose to do something, as often as not it ends up being a situation where we split a whole chunk of functionality off as a separate app.

I can respect the fact that you have that opinion. We (the development team I am a part of) don’t share that opinion and disagree with the conclusion. We all have backgrounds with large Java-based projects and have concluded that the “one-class-per-file” default standard is extremely counter-productive and have found much practical benefit in the “fewer-files-are-better” approach.

Dear @KenWhitesell ,

Thank you for your detailed response and for sharing your experience with managing large Django projects. Your insights on the impact of increasing file numbers on clarity and organization are very pertinent.

I understand your perspective that splitting a models.py file into several smaller files does not always guarantee improved readability or maintainability, especially in complex projects. However, my initial proposition was to explore the technical feasibility of separating models into distinct files within Django, not necessarily to debate its practical efficacy. To my understanding, Django technically allows this separation, although it is not a common or recommended practice in the Django community.

I fully respect your approach of functionally dividing functionalities into different applications when justified, which is different from my suggestion of distributing models across multiple files within the same application for clarity in specific cases. Your advice to favor fewer files for better overall management is well taken and will surely be helpful to many developers.

Once again, thank you for your time and for sharing your valuable insights. Your contributions greatly enhance our collective understanding of best practices in Django development.

Best regards.