Welcome to my project on Django Conventions. Below I will try and lay out a list of basic conventions that should be used when creating Reusable Django Applications. Nobody is going to force you to follow these rules, but I think that they will be a good reference point for Best Practices and Conventions. Please contact me if you have any questions or leave comments below. If this page is useful, please feel free to suggest more conventions that are applicable.
This project going to be integrated with django reusable app docs over time. I have a mirror of my sphinx docs here
I have split this up into two separate pages to make things a bit easier.
Django Inspect: A generic introspection API for Django models
3 weeks, 6 days Ago (Comments: 4)
The role of designers in the Django community
1 month Ago (Comments: 7)
Large Problems in Django, Mostly Solved: Documentation
1 month, 1 week Ago (Comments: 5)
2 months Ago (Comments: 0)
Correct way to handle default model fields.
3 months, 3 weeks Ago (Comments: 8)
I may not have gone where I intended to go, but I think I have ended up where I intended to be.
- Douglas Adams


Comments
1 David Zhou says...
Do we still need to mention the Meta class for models?
Posted at 7:28 a.m. on December 4, 2008
2 David Zhou says...
Oops, submitted too soon.
I meant, do we still need to mention the meta class for models and other orderings when that's already in the docs?
Posted at 7:33 a.m. on December 4, 2008
3 Joel Pittet says...
One thing I like to do in my templates is make a block for JS and CSS in addition to extra_head. The reason is that I put the CSS above the JS because the CSS can load in parallel where the JS cannot and can end up blocking the page load till all are complete. I usually put these blocks under any frameworks or basic CSS files to allow them to extend/overwrite the ones above. Some of the new browsers are starting to allow parallel JS files, but this is just a trick to get the page rendering before the JS needs to execute.
Posted at 7:44 a.m. on December 4, 2008
4 David, biologeek says...
Those conventions should be in official doc, great work!
About fixtures, you must use fixtures/initial_data.json name if you'd like to add some initial data during syncdb.
For templates, I prefer to put them at the same level as the app and doc folders but YMMV.
Very often I use APP/consts.py to store all sort of constants (integer <-> description for choice fields for instance).
Another convention I had adopted is to import views in urls and do not use strings but directly python fonction to define my urls, this way it breaks really fast if a function doesn't exist or whatever.
Posted at 9:04 a.m. on December 4, 2008
5 No' says...
And why not building a django test suite that would check if these conventions are respected? A bit "à la" pylint... or a program that imports the settings.py files dans for each application which is not in "django.*", checks every bit that is checkable, throwing warnings and advices whenever it's possible?
Posted at 9:42 a.m. on December 4, 2008
6 Jiri Barton says...
Good work! I also would like to see how one should layout the whole project -- if this is page is the right place for it.
Where do you put the reusabble applications, the applications specific to the project, and django itself?
Posted at 11:18 a.m. on December 4, 2008
7 Dan Fairs says...
For me, packaging is a huge issue. People releasing apps is all well and good, but too often it's in a form that's difficult access.
Python itself has an approach for this: eggs. There's no reason Django apps can't be packaged as eggs; projects can too. I've even created some Paster templates to help. Just:
easy_install fez.djangoskel
James Bennett's done a great job packaging and releasing his applications on PyPI. django-registrations and django-profile are now just an easy_install away (or, in my case, dropping a line in my buildout script).
This approach isn't 100% perfect yet - there are still issues around static media. But at least starting with the standard Python approach for packaging has got to be a good thing!
As these recommendations go on, I'd be happy to incorporate them (as far as possible) into the paster templates above.
Posted at 11:56 a.m. on December 4, 2008
8 Jannis Leidel says...
Additionally here is another good list: BestPracticesDateinamen/
Since it's in German here the translated version: DjangoBestPracticesFilenames
Posted at 12:11 p.m. on December 4, 2008
9 Rock Howard says...
For apps that are intended to be reusable and incorporate example projects, I prefer the Pinax convention: The top level directory contains a "projects" directory and any example projects are placed within it with one project per subdirectory.
I prefer a "tests" directory over tests.py and this possibility should be mentioned and allowed.
In my opinion it is too early to standardize on a distribution mechanism, but perhaps a section on the most common mechanisms is in order (i.e., disutils, "place on PYTHONPATH", and self-install a la Pinax.)
There are additional files that are commonly seen in python packages that should be considered for inclusion in these conventions: README, LICENSE, AUTHORS, INSTALL, CHANGELOG, MANIFEST.in, DEPENDENCIES, ROADMAP, ...
Posted at 12:21 p.m. on December 4, 2008
10 David, biologeek says...
@Jiri : here is my current tree for my django projects:
I'd love to discuss on this topic!
ps: @Eric, it seems that markdown <pre> doesn't work?
Posted at 12:31 p.m. on December 4, 2008
11 David, biologeek says...
Note: markdown <pre>view doesn't work ;-)
Posted at 12:32 p.m. on December 4, 2008
12 Rock Howard says...
Let's also include Bennet's coding conventions for views and forms which can be summarized as:
Views should provide keyword arguments with reasonable defaults in the general manner of Django's generic views. In particular:
template_name The template that the view renders in normal processing.
extra_content A dictionary that is added to the content dictionary that is sent to the template.
In addition, if your view is performing forms processing, then add these keyword arguments:
form_class The class of the form to be created.
success_url The target of the redirect in the case where the form is processed successfully.
Example view with recommended keyword arguments:
Posted at 12:33 p.m. on December 4, 2008
13 Keyton says...
Thanks, Eric, for all the great work. You might take a look at Bennett's book on Practical Django. I believe he covers the class layout thing pretty well too (not sure it has more or less than yours as I don't have the book with me at the moment).
Being a django noob, here are some other things that seem to not really exist in one tidy place: 1. An example file tree for a "real" project (maybe one with multiple apps). Pinax is good, but is it best practice? This is basically an amalgamation of what you have above. 2. Clear talk on site media layout etc. There's LOTS of this out there but no article I've seen to date really pulls it all together. 3. Maybe outside the scope, but some best practices for development process (local_settings, and the like) might be good to cover.
Posted at 12:46 p.m. on December 4, 2008
14 Shawnr says...
This is a great page so far. I'm glad to see a lot of things we already do, and some things that seem like good ideas. But I also have a question/suggestion:
We often build apps that have custom admins to support very complex business logic (this practice started long before 1.0 and new-forms admin; perhaps now the admin is flexible enough to elegantly support our needs). As a result, we found that having a single views.py and urls.py file did not fill our needs.
Our practice is to put views in APP/views/ and to put URLs files in APP/urls/. This way we can have APP/views/public.py and APP/views/admin.py. We have found that on large projects this organization helps keep things tidy. Any thoughts about supporting a conventional approach to multiple URLs and views files?
Posted at 7:59 p.m. on December 4, 2008
15 Eric Holscher says...
I have updated the above to reflect all of the great suggestions in the comments. Thanks so much for all the great feedback!
Posted at 8:05 p.m. on December 4, 2008
16 Shane Graber says...
What would be nice would be to use paster to create an app with these conventions. A paster template already exists, but maybe it could be modified to take into account these conventions: http://www.stereoplex.com/two-voices/fez-djangoskel-djang...
Shane
Posted at 2:06 a.m. on December 5, 2008
17 Robert Lofthouse says...
For quite a while now my project structure has been:
UGC is stored elsewhere.
Whenever I consult for various startups I try to get them into that kind of structure. They almost always don't modularise anything at all (one models.py, one views.py etc).
Posted at 2:36 a.m. on December 5, 2008
18 Milan Andric says...
I'm surprised not to see the named urls convention that seems to be prevalent. Maybe it's so basic it doesn't need mention?
Posted at 7:57 p.m. on December 11, 2008
19 Antonio Melé says...
I translated project conventions into Spanish: Convenciones de proyecto en Django
Posted at 11:25 a.m. on March 10, 2009
20 Brandon says...
I like the idea of having a {% block onload %}
and then put that in <body onload="{% block onload %}{% endblock %}">
now when i'm creating parts of my app that need an onload function to happen, i can easily do so. do we not use onload anymore? I'm not very experienced, just sharing my method.
Posted at 9:24 p.m. on April 2, 2009
21 Rabubbeatly says...
Hi there, my home page is http://www.google.com
Posted at 5:59 a.m. on October 16, 2009
22 ShumebypeGype says...
Hi there, my home page is http://www.google.com
Posted at 3:28 a.m. on October 22, 2009
23 julian says...
Brandon Says: do we not use onload anymore?
Some people do, I guess. It works of course, but is a bit outdated. I use jQuery on almost all of my apps, so instead I have a {% scripts %} tag for normal scripts unique to a page, and a {% jquery %} tag for code that goes in the jQuery document.ready area. document.ready takes place of body.onload. If you need to fire out definitely after everything is rendered, you can do $(window).load, too in jquery.
Posted at 12:30 p.m. on December 26, 2009