integrating third-party django apps and templates - django

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 and settings.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.

Related

django - when url namespace should be used?

I mostly read that it should be used with 3td party apps. But if I have my own many local apps, does it make sense to give each its own namespace?
This way I can know which url belongs to which app. Rather then relying on "name "solely.
Typically namespacing would be useful if you need to reuse the apps (e.g. make a part of your app a module that you'd use in another app), or build sites that contain multiple apps (e.g. two projects sharing the same user database). Another case is if you want to keep specific features of your project well-separated, you could make them into separate apps with their own namespace and their own urls.py.
There may be a few cases, if you're using incorrectly namespaced apps as modules of your own app, where there'd be conflicts.
Namespacing urls.py isn't the only thing you should do to reuse apps: You may want to put all your templates and static files in subfolders, as the way they're collected flattens the structure. e.g. your templates would be in my_project/my_app/templates/my_app/template.html
If you are certain that what you are developing will be standalone, there may be no need for namespacing.

How and where should I put a version number in my Django project?

I'm making a Django project consisting of several apps and I want to use a version number for the whole project, which would be useful for tracking the status of the project between each time it comes to production.
I've read and googled and I've found how to put a version number for each django app of mine, but not for a whole project.
I assume that the settings.py (in my case it would be base.py, because the settings are inherited for each environment: developmente, pre-production, production) would be the ideal file for storing it, but I would like to know good practices from other Django programmers, because I haven't found any.
Thank you in advance
I don't think I've ever needed to do this, but the two obvious choices would be either the settings file, as you state, or alternatively the __init__.py in the main project app.
You don't need it to relate to django, you can tag a commit in your source control to provide a marker of a particular version (as well as a separate branch for releases).
From the docs for git tagging
Git has the ability to tag specific points in history as being important. Typically people use this functionality to mark release points (v1.0, and so on).
You could use the same versioning number system as google if you so wish which relates to
year.month.day.optional_revision # i.e 2016.05.03 for today
Doing this would make it easier to track back to previous versions since it won't be overwritten in source code by newer version numbers.

Splitting static files in my webpage - What are the trade-offs?

I am currently involved in a Django project and I am definitely using Twiter bootstrap for the layout.
Though not actually precise, my question is quite simple: Bootstrap allows me to choose which styles/JS I want to download separately -- forms, tables, responsive, styles for buttons, navigation, etc -- and also together in a single "all-inclusive" file.... and I am not using all the resources at once on the same page.
Additional to that, we have the Django template system, which allows me to build one template over another, so I can basically add the more general stuff to my base template and, as I need in subtemplates, include the other static files.
So, to sum up everything: Is it worth it, to have those styles separated? I think that in terms of organization maybe it is not so clean, because I will have to import and handle more CSS files, but on the other hand I won't be loading unnecessary stuff.
What are the trade-offs of this choice?
Thank you for your time.
Is it worth it, to have those styles separated
No it is not. If you look around, e.g. visitmix, you'll see that the overhead of requestig new files make the difference neglible.
Server you static from a cookie-less domain and you'll users will only have to hit your servers twice: once for CSS and once for JavaScript.

Module overriding in Joomla 1.6

I am new to Joomla, started learning it just a day ago and didn't manage to find an answer to my question in the docs (which suck real bad compared to Drupal).
So what I want to do is override the whole module in a template. The documentation only suggests I can override the markup of a module by placing corresponding files in the html folder, but I have to make some corrections to the actual logic. Is copying the module, changing and then installing it as a separate entity the only way to go? I mean it makes sense that "template" folder is for "views" but with the kind of application I have to develop it is gonna be annoying...
Yeah, you can only override views.
If you want to override logic, you have 2 options:
Change the actual logic in-place, which leads to problems on updating etc
Duplicate the module and change the logic, as you suggested
One other way to consider is to replicate or fix the logic in the template. While this is not a very slick way of doing it, it is faster, especially than duplicating a whole component.
Note that you can also add your own libraries to the Joomla libraries folder to centralize your own code.
Further, if you manage your code with (for example) svn, you should not have any problems on upgrades with creating new views that may include their own logic.

django -- application subdirectory site/app1/app2/app3

If you were to write an app for a site, but wanted to make the app plug&play so you can just drop it in any Django project, set the main URL and there you go, how would you do that if you wanted to keep all the other required utility apps included in your portable app.
Example:
site/
site/site-app1
site/templates/site-app1
site/util-app1
site/util-app2
site/util-app3
Note: that the site-app1 makes the use of all three util-apps. It works great in this manner. But now, you decide to send the app to someone, but just that app with all its dependencies.
If we could package and send the apps like this?:
site/site-app1
site/site-app1/template
site/site-app1/util-app1
site/site-app1/util-app2
site/site-app1/util-app3
Then you just send site-app1 and everything goes with it.
Is there a way to make portable with utility apps as subdirctories?
Note: the idea is that we don't want to send the whole project, but one site-app within
the project only.
There have been a few presentations about reusable django apps, so search around. These should get you going:
Developing reusable apps. pdf and video
Django Templates: The Power of Inheritance
The presentations #Gerry links to are good sources of general info. To answer your question more directly, there isn't a way to package one app inside of another one (EDIT sorry, this is just plain wrong. You can put one app inside of another one's namespace, and it works just fine. It's an odd thing to do though: you're implying that the one app is a part of the other one; if that's true they'd be easier to use as a single app. So I'd still recommend one of the below options). AFAICT your options are:
If possible, make those external dependencies optional (i.e. enhanced functionality if util_app1 is available, fallback behavior if it isn't). This is how many apps behave with respect to, say, django-tagging or django-mailer.
Roll all the functionality into a single app. Depending how much code you actually depend on from the utility apps, if the dependencies are absolutely necessary for your app to function, this might be the best option to make things easy on your users.
Package and distribute all the apps separately and note the dependencies both in the documentation and in the setup.py install_requires. If all the apps are independently useful, this approach may be best. If they aren't all independently useful, why are they all separate apps?
Django applications can be made portable by adhering to certain practices. Ofcourse, these are not mandated
Application Location
The convention is to add applications in an apps/ directory, and to modify the manage.py (and eventually the apache config) to include
import sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
Your directory structure will look something like
site
site/apps/
site/apps/app1/
site/apps/app2/
Templates
Templates are located in the templates directory in the application. The convention is not to force the user to copy them in any other location. Eventually the user can have global templates to override the ones in the application.
Settings
Keep all default settings in a local file within the app directory. The settings would be overridden by the global settings. The local settings file will have the following structure..
from django.conf import settings
def get(key, default):
return getattr(settings, key, default)
SETTING_1 = get('SETTTING_1', 10)
These conventions should cover most major issues.