Template Structure: App vs Project

One of the great subjective debates in Django is where to place apps. Personally I prefer project-level for personal projects or on smaller teams. It helps me find and think about them more easily. This means creating a “templates” directory and updating the DIRS config in settings.py.

So for a Blog app:

├── blog
│   ├── app stuff...
├── blog_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── templates
    └── post_detail.html

But for larger projects and especially when using 3rd party packages, probably app-level is more preferred albeit (in my opinion) a little more of a hunt to find the proper template. Same blog would look like this:

├── blog
│   ├── app stuff...
│   ├── templates
│       ├── blog
│           ├── post_detail.html
├── blog_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py

Does this match others experience?

For several years, my goto project structure is:

├── blog
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── test_settings.py
│   ├── urls.py
│   └── wsgi.py
├── templates
│   ├── blog
│   │   └── post_detail.html
│   ├── base.html
│   └── homepage.html
├── manage.py
├── docker-compose.yml

Highlights:

I always call the main project config which is nice when you deal with enough projects that you don’t want to guess where to look for project configs.

I only use two settings files. settings.py reads environment variables via django-environ. My test_settings.py only override a half dozen to a dozen settings to speed up CI/local tests.

I’m not a fan of app-level templates if they are bundled in the main project repo because it’s yet another place to have look to figure out what’s going on.

If your goal is to make your apps reusable over other projects, then you should unbundle them and treat them like third-party apps. I’m not a fan of running your own pypi, but thankfully pip makes it easy to install your application via a git repo which avoids having to add extra infrastructure/overhead to your project.

1 Like

I like the idea of calling the project “config”. Helps clarify. I’ve been more apt to call it “blog_project” or whatever just to be clear it’s not an app. Of course, as apps increase not uncommon to have an apps directory. But one thing at a time.

1 Like

I have worked with several projects apps namespaces over the years, and it felt unnecessary and kind-of weird. I’m -1 on the practice because it feels like an anti-pattern because namespace collisions feel far more common concerning third-party packages.

This may have changed, but I ran into problems with third-party modules trying to use get_model, which wants model_name with the app_name.ModelName format. This used to ignore namespaces more than one level-deep, which would blow up if you had two third-party modules that used the same app names. The solution would be to rename the internal app’s module name, but I felt like flattening apps make using unique modules slightly more straight forward. Then again, maybe this was just my experience.

I’ve been using this approach of naming the main project configuration for some time as well. Big fan! I pretty much always follow the templates-in-app-directories convention because I prefer consistency across my projects over the simplification of any one particular project. If a project I’m contributing to or collaborating on hasn’t gone that route, I don’t mind much though.

Yeah, so I do exactly what Jeff says he doesn’t. :stuck_out_tongue_winking_eye:

I have project level templates but if there’s a blog app with views, I’ll put the templates for those views in the app, right next to them. Generally, I prefer that.

But either way works. Be consistent matters more than which you choose I’d reckon.

1 Like

I did the template in the app repo for many years and even used a series of templates inheritance to theme websites. As soon as one or two apps need to share the same base set of templates, it gets more confusing that it’s worth. This can be more common when you have two or more websites that need to override the base set of templates and you have to have three or four folder locations up to make a change.

That said, it’s a handy technique to use if that isn’t your use-case.

Yes, I can see that.

One way of looking at it may be, Are you spending more time in the related the views or in the related templates?.

If it’s the views then the having the templates in the app is handy. If it’s the templates then, yes, you’re probably going to be better served moving them to the project level.

One nice thing about this question is that you can just move ‘em — as long as you named them following the conventions, no other changes should be needed. (I think :grinning:)

1 Like

I like to keep templates and assets separated from the apps, so that all front-end stuff is separated from the back-end stuff. This way there is a single place for front-end devs to work in.

My goto structure is usually:

├── project
│ ├── app1
│ │ └── models.py
│ │ └── urls.py
│ │ └── views.py
│ ├── appN
│ ├── environments
│ ├── init.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── templates
│ ├── app1
│ │ └── js
│ │ └── scss
│ └── appN
├── assets
│ ├── app1
│ └── appN
├── .env
├── .gitignore
├── Pipfile
└── README.md

My daily struggle is where to put the common stuff, like BaseTestSetup classes and non-app specific mixins. Since the apps all end up tightly coupled… :confused:

(and I always really wished there was a convention for this, as I also can’t shake the feeling what I’m doing is completely wrong)