I'm new to Django and fairly confused about how third-party apps are best integrated. In my (possibly naive) interpretation of DRY, I want to minimize copy/pasting not only my own code but other people's code as well, so I'm happy with, for example, the pattern of using contrib.auth as mostly a black box if I needed additional info on auth.User (by extending auth.User with a UserProfile object or inheritance). And this was how I imagined I'd use most third-party apps as well.
However, I quickly found out this was very difficult, so now I've resigned to having "copies" of all of my third-party apps living inside my project folder that are basically entire copies with minimal changes. The final straw was me wanting to add a basic blog (I settled on django-basic-blog) and needing to just change a single template, and I thought of no better solution than just making a copy of that app inside my project with the single template changed.
My questions:
- in this specific case where I need to change just a single template, is this (copy the entire app over) the best I can do? If I just needed to change a single model I can keep the third-party app respectfully intact and do a model inheritance in my own app...
- in general, this practice of copying the apps under my project and patching each a tiny bit feels crazily wasteful and dirty. It also feels like if I'm using a frequently-updated third-party app it will be a pain to sync the changes. Should I just learn to love the bomb or is there some obvious architectural pattern / Django-provided assistance I am missing?
You should not modify the code of 3rd-party modules, as it's hard to track the changes and it creates a mess with the same code copied into many projects. Typical solution is to have only one version of each third-party module in your python path, not in your project's dir. This single package can then be reused by all of your projects.
However different approach is needed for templates, as they often need to be modified on a per-project basis. That's why Django comes with
settings.TEMPLATE_DIRS
andsettings.TEMPLATE_LOADERS
.TEMPLATE_DIRS
specifies list of directories containing template files.TEMPLATE_LOADERS
specifies the classes used to load templates. The loaders will be used in order they were defined and the directories will be traversed in order they were defined. So you can look for templates in your project's directory first and in other modules as a fallback.So basically you do not need to copy the entire python module in order to change one template. Copy just the templates directory of that 3rd party module or even just the single template you want to change. If you'll put in the right place and add have the path in
TEMPLATE_DIR
Django will use it.