Best way to structure a django project with multiple levels of sub apps?

479 views
Skip to first unread message

Alexander Joseph

unread,
Aug 17, 2017, 5:26:24 PM8/17/17
to Django users

I'm bullding a larger django project and I'm starting to implement cookiecutter django after reading through "2 Scoops of Django" but still have some questions on structuring a project.


I've setup my project, we'll call it 'business_proj'. In business_proj I started an app called 'accounting' this might have an accounting dashboard for users in the accounting security group. Now, what if I want to have apps that belong to accounting, such as 'invoices' and 'purchase_orders'? Should I create those apps inside my accounting app? Or should I create all my apps in the main project root? The way I've started doing it is creating child apps inside of their parent apps but some parent apps are so big that even this gets messy. 


ie.



my_project/
    config/ 
    docs/
    accounting/
        invoices/
            __init__.py
            admin.py
            models.py
            urls.py
            views.py
        purchase_orders/
            __init__.py
            admin.py
            models.py
            urls.py
            views.py 
        __init__.py
        admin.py
        models.py
        urls.py
        views.py
    engineering/
        products/
            product1/
                sub_product1/
                    __init__.py
                    admin.py
                    models.py
                    urls.py
                    views.py
                __init__.py
                admin.py
                models.py
                urls.py
                views.py
            product2/
                __init__.py
                admin.py
                models.py
                urls.py
                views.py
            __init__.py
            admin.py
            models.py
            urls.py
            views.py
    requirements/
    utility/


it gets messy especially under 'engineering' since there are so many sub apps and sub levels in the engineering app. I dont really want to have all the apps just under the main project through because by the end of the project there could be over 100 apps and I'd like a way to keep everything somewhat organized so as to not drive myself insane.


Is there a better way to do this? Or are there any pitfalls I need to watch out for doing it this way? Would it be better to simply make an 'engineering' folder (not module) in my project and store all the engineering related projects in that folder?Thanks

James Schneider

unread,
Aug 18, 2017, 4:31:41 AM8/18/17
to django...@googlegroups.com


On Aug 17, 2017 2:26 PM, "Alexander Joseph" <alexander...@gmail.com> wrote:

I'm bullding a larger django project and I'm starting to implement cookiecutter django after reading through "2 Scoops of Django" but still have some questions on structuring a project.


I've setup my project, we'll call it 'business_proj'. In business_proj I started an app called 'accounting' this might have an accounting dashboard for users in the accounting security group. Now, what if I want to have apps that belong to accounting, such as 'invoices' and 'purchase_orders'? Should I create those apps inside my accounting app? Or should I create all my apps in the main project root? The way I've started doing it is creating child apps inside of their parent apps but some parent apps are so big that even this gets messy. 


What you are calling 'apps', I would call models. PO's and invoices are part of larger workflows. There's no technical reason, or even from an organization perspective, to create that many apps.

<snip>

Is there a better way to do this? Or are there any pitfalls I need to watch out for doing it this way? Would it be better to simply make an 'engineering' folder (not module) in my project and store all the engineering related projects in that folder?Thanks

I think if you better define an app vs. a model, you'll find that you need only a few apps.

IMHO, an app should represent a logical segment of your project, broad enough that a majority of the business logic is self-contained and relies little on other apps. Apps should be very high level.

In your case, you would likely have apps for 'accounting' and 'engineering', along with other distinct units within the business. The business processes and logic for engineering have little or no overlap with that of accounting. Same with HR, IT, and so on. That's literally as detailed as your apps should be, in which case you'll probably end up with a dozen or so at worst. If it were me, I'd have even less than that with even larger groupings, maybe something along the lines of 'sales' and 'operations' as the only two apps.

One of the key ideas to help understand here is that a Python file containing models does not have to be called models.py. In fact, I usually don't have a models.py at all. Instead, I create a Python module within the app called 'models', which is nothing more than a directory named 'models' that contains __init__.py and all of the Python files that contains my models. Each of those files contains models that are further separated logically. The structure looks like this (some structure omitted for brevity):

business_proj/
    engineering/
        models/
            __init__.py
            abstract_design.py
            abstract_manufacturing.py
            abstract_quality_assurance.py
            design.py
            manufacturing.py
            quality_assurance.py

You could also bury the abstract models in their own module using the same pattern. 

Assuming you have 'engineering' as a registered app, your __init__.py would look

James Schneider

unread,
Aug 18, 2017, 5:00:22 AM8/18/17
to django...@googlegroups.com


Once again, I accidently sent this email. Not a fan of the sensitivity of the screen on my new phone. Continued below.

I think if you better define an app vs. a model, you'll find that you need only a few apps.

IMHO, an app should represent a logical segment of your project, broad enough that a majority of the business logic is self-contained and relies little on other apps. Apps should be very high level.

Forgot to mention one exception. I always have a 'common' app that contains all of the models (or views, etc.) used by multiple other applications. In a majority of cases, these are abstract models I use for all of my concrete models in other apps that include fields for auditing such as created_by and created_on. Other examples would include abstract models for addresses, and master views that include logic such as requiring a user be logged in used as mixins for other apps.


In your case, you would likely have apps for 'accounting' and 'engineering', along with other distinct units within the business. The business processes and logic for engineering have little or no overlap with that of accounting. Same with HR, IT, and so on. That's literally as detailed as your apps should be, in which case you'll probably end up with a dozen or so at worst. If it were me, I'd have even less than that with even larger groupings, maybe something along the lines of 'sales' and 'operations' as the only two apps.

One of the key ideas to help understand here is that a Python file containing models does not have to be called models.py. In fact, I usually don't have a models.py at all. Instead, I create a Python module within the app called 'models', which is nothing more than a directory named 'models' that contains __init__.py and all of the Python files that contains my models. Each of those files contains models that are further separated logically. The structure looks like this (some structure omitted for brevity):

business_proj/
    engineering/
        models/
            __init__.py
            abstract_design.py
            abstract_manufacturing.py
            abstract_quality_assurance.py
            design.py
            manufacturing.py
            quality_assurance.py

You could also bury the abstract models in their own module using the same pattern. 

Assuming you have 'engineering' as a registered app, your __init__.py would look

something like this:

from .design import *
from .manufacturing import *
from .quality_assurance import *


This let's Django find all of the models to create the migrations accordingly.

Imports of these models in other locations can also much more objective:

from engineering.models.design import WidgetOutline

In reality, this also works as an alternative because of the __init__.py setup:

from engineering.models import WidgetOutline

But that is slightly less verbose. Your call.

Views and forms (and probably URL's) can be organized using the same pattern. There's no automatic discovery process like models have; views, forms, and URL's can live anywhere with any legal Python name since they are manually imported wherever they are needed. Theoretically your entire project can run inside a single monolithic file.

HTH,

-James

Reply all
Reply to author
Forward
0 new messages