Currently I work mostly on a large Django code-base 4+ years old in which business logic is tangled throughout the three MVC components.
Given such a large framework, developers often forget how to write well-organized Python business logic code they’re definitely capable of given the absence of the framework.
As someone who has worked on projects with these symptoms, as well as other older code bases before my Django days, the situation isn’t as bad as some very old PHP projects I’ve seen. Anyway, here are some tips which can be applied to Django applications to aid in organization overall.
Keep only database code within the models module
You’ll often see lengthy ORM queries randomly plastered throughout an application. Keeping these within the model class makes everything more maintainable.
- Place ORM queries within your models module
- Define custom managers and queryset sub-classes where appropriate
- Wrap up the queries you need using these features
- Keep business logic out of here
Create modules for business logic
As you would with a regular Python program. Create your own modules outside of Django component structure.
Make your logic functions responsible only for logic, as in not caring about the presentation or data layer (use dependency injection).
Views should be light
Your views should only be used to glue things together, linking requests to forms, forms to your business logic and outputs to templates.
The view then becomes a simple description of how a feature is coupled.
Override forms for validation
- Override the Django form methods to add any complex custom validation.
Keeping all of your validation code inside the forms module means errors can always to tied back to the individual inputs.
A result of the above rules is increased testability, easier adaptability and of course it’s in-keeping with the separation of concerns design principal.
One other thing is to break out your code into separate apps – if your models.py starts getting too big, it’s usually a sign you need to split out your app into multiple apps.
e.g. when working on e-commerce sites in the past, we’ve had one separate one app for the products, and another for customer orders. An order is related to a product (in that an order will have one or more products associated with it), but otherwise, it’s a completely separate concept and it’s easier to keep the code separated.