Models.py is getting huge, what is the best way to smash it?

Directions from my supervisor: โ€œI want to avoid using any logic in models.py . Now you can use it as soon as classes to access the database and store all the logic in external classes that use model classes, or wrap them "

I feel this is the wrong way. I feel that keeping logic from models just to keep the file small is a bad idea. If logic is best in the model, then where it really should go regardless of file size.

So is there an easy way to just use? In PHP-speaking, I would like to suggest to the supervisor that we have models.py include () model classes from other places. It is clear that this would allow the models to have all the logic that we want, but reduce the file size by increasing the number of files (which leads to less versioning problems, such as conflicts, etc.).

So, is there an easy way to remove model classes from the models.py file, but still models work with all Django tools? Or is there a completely different but elegant solution to the general problem of the โ€œlargeโ€ models.py file? Any input would be appreciated.

+79
python django django-models models
Jul 21 '09 at 17:27
source share
3 answers

Django is designed to create many small applications instead of one large application.

Every large application has many small applications that are trying to free themselves.

If your models.py feels great, you are doing too much. Stop. Relax. We lay out.

Find smaller, potentially reusable application components or parts. You do not need to reuse them. Just think of them as potentially reusable.

Consider your upgrade paths and lay out the apps you might want to replace some day. You do not need to replace them, but you can consider them as an independent โ€œmoduleโ€ of programming, which in the future may be replaced by something cooler.

We have about a dozen applications, each model.py is no more than 400 lines of code. They are all pretty focused on less than half a dozen discrete class definitions. (These are not hard limits, these are observations of our code.)

We decompose early and often.

+61
Jul 21 '09 at 17:32
source share

Naturally, model classes contain methods for working with the model. If I have a book model with the book.get_noun_count() method, where it belongs, I donโ€™t want to write " get_noun_count(book) ", unless the method essentially belongs to another package. (Maybe, for example, if I have a package for accessing the Amazon API with " get_amazon_product_id(book) ".)

I shrunk when Django's documentation suggested placing models in a single file, and I took a few minutes from the start to figure out how to split it into the correct subpackage.

 site/models/__init__.py site/models/book.py 

__init__.py looks like this:

 from .book import Book 

so I can still write "from the book import sites .models."




For versions prior to Django 1.7, only the following is required: https://code.djangoproject.com/ticket/3591

The only trick is that you need to explicitly install each model application due to an error in Django: it is assumed that the application name is the third to the last entry in the model path. "site.models.Book" leads to a "site", which is correct; "site.models.book.Book" makes us think that the name of the application is "models". This is a pretty nasty hack on the part of Django; he should probably look for a list of installed applications to match the prefix.

 class Book(models.Model): class Meta: app_label = "site" 

Perhaps you could use a base class or a metaclass to generalize it, but I have not worked on this yet.

+91
Jul 21 '09 at 18:02
source share

I cannot decide which of the many possible problems you may have. Here are some answers:

  • several models in one file

    Put them in separate files. If there are dependencies, use imports to pull in additional models.

  • extraneous logical / utility functions in models.py

    Put additional logic in separate files.

  • static methods for selecting some model instances from the database

    Create a new Manager in a separate file.

  • obviously related to the model

    save, __unicode__ and get_absolute_url are examples.

+4
Jul 21 '09 at 18:42
source share



All Articles