Lately I have been thinking a lot about how well Django adapts to new users. I noticed that there seems to be an influx of first-timers. Although these programmers come from a variety of backgrounds, there are some areas within the framework that consistently cause stumbling blocks. In a lot of ways it is part of the reason that I’ve devoted a segment of This Week in Django to the subject. So what can be done to make Django more new user-friendly?
Convention Over Configuration
The idea of convention over configuration was really brought home with the Ruby on Rails framework. At almost every opportunity Ruby on Rails provides a default convention. David Heinemeier Hansson, the creator of Rails, calls it “Opinionated Software.” It definitely is opinionated. So much so that in some cases it is the reason why people do not embrace the framework. I’m not suggesting that Django does “convention over configuration” to the same extreme that Ruby on Rails does, but there are things that can be learned from Rails.
Sensible Settings
So what sort of things am I talking about? First, as an example, the ADMIN_MEDIA_PREFIX should default to something other than /media/. Most new developers to Django want to put their media at, well media. And as a result they end up having trouble serving up the Admin’s media files. So you say, there’s nothing stopping them from changing one or the other. Sure they can change the defaults, but that is not going to be their first response. Instead they are going to spend a lot of time trying to figure out why it does not work. So if the ADMIN_MEDIA_PREFIX was something like /adminmedia/ by default this would cause a lot less confusion.
“The whole global_settings.py is about defaults!” you say. So am I being nit-picky? Sure I am. I want Django to be the best damn framework on the planet. Plus, this post is not about ADMIN_MEDIA_PREFIX, it is really about making Django more palatable to new users. A good exercise would be to go through all the default settings and really think about them from the standpoint of a new user. For instance, should the TIME_ZONE information be pulled from the system environment? In some cases, perhaps we just need better documentation. In other words there’s not a sensible default, but perhaps we could clear up areas of confusion around the differing possibilities.
A Place for Everything
The other area where Django could could use some more convention is in “where things go”. The most often asked question about NewForms has nothing to do with using NewForms or making NewForms work. The most often asked question is “Where should I put my form class?” Yes, for those of you familiar with Python and Django this seems ridiculous. You say, “It’s a python module, put it wherever you want!” And you’re right, but a lot of “newbies” to Django are “newbies” to Python. They are coming to Python through Django. In fact that the case for myself. Yet, none of these “newbies” are asking “Where do I put my views?”
So given the audience, “convention over configuration” makes a lot of sense and saves a lot of repeated questions around the same types of issues. Someone who is new to the framework doesn’t really have an opinion about what is best, but they generally want someone to tell them “this is the way to do it.” Therein lies the confusion.
So how can we accomplish that? I can think of two solutions.
First we can provide more templates when the startapp management command is used. This would work much in the same way as the views.py module template is provide. A blank module with some comments and perhaps an import or two.
So the positives of this approach are that it would answer the question. There would be a “place for everything and everything is in its place.” But the negatives are that, well “everything would be in its place.” So where does it stop? Do we provide a managers.py, feeds.py, and signals.py templates? I think Ruby on Rails overdoes it with all the structure and files. You end up with the opposite problem of not knowing where anything is—not sure if you’re using the right bucket for the right purpose. So there’s got to be a balance somewhere.
The second solution is to provide more generators, management commands, to create these things on an as needed basis. I like this approach much better because it makes it real easy to ask the framework “I need a form. Please create one for me.” As you get more experienced with the framework, and develop your own “best practices,” you may or may not continue to use the generators, but at least they are out of the way and available if you want them.
If these management commands were to take a note or two out of the play book of Ruby on Rails, they could end up being quite convenient. For instance, there could be a management command that looks like:
./manage.py create form appname FormClassName
This could generate the forms.py module in the appname specified, where it has the FormClassName defined with all the correct imports. Likewise, we could have something like:
./manage.py create modelform appname ModelName
This would generate the forms.py module in the appname specified, with the ModelForm class defined and the inner meta for the model defined.
What Do You Think?
Clearly this is not going to be everyone’s “cup of tea,” but the great thing about this approach is that you don’t have to use it.
So, do you agree or disagree? Do you have other ideas about this “problem”, or do you think there is no “problem” to be solved in the first place? I look forward to hearing your thoughts, questions, criticisms.



Good points—this is something I agonize about constantly. It’s unfortunate, but it often seems that the needs of new users conflict with needs of more advanced ones. That is, an advanced user is going to start by deleting 99% of the boilerplate generated by any automated tool, but to a beginner that boilerplate is a godsend.
The best proposal I’ve heard is something like a ”./manage.py startapp—complete” command (call it whatever…) that would generate not the lightweight simple app but a complete one with a forms.py, urls.py, etc., etc., etc.
When I first started with Django I struggled with “where does x go” questions quite a bit. Finally over IRC someone (I forget who) basically said it’s a Python module, put it wherever you want. And that did it.
I don’t think the create-a-place-for-everything path works too well. I spent quite a while thinking views.py was magic and putting all my views in there. More default boilerplate would lead to more mis-placed belief in magic for novice users.
I think a nice, short, prominent piece somewhere in the tutorial that simply says: “there’s no magic, you can put your X anywhere, but you might want to put it in X.py” would be a good solution. Even novices can be smart if they’re provided with the right information in a clear, concise way.
I’m about to start my Django journey, haven’t used Python earlier either so I recognize myself in the text. Your second suggestion about using manage.py to create stubs sounds much better than the first suggestion. Having alot of files created at once would probably just scare me away, I like it clean and Django/Python seems like a really good combination.
This is a minor nitpick, but I find it odd that even with USE_I18N set to True, the admin HTML template doesn’t declare a utf-8 charset.
It seems like this would be a reasonable default with internationalization turned on.
I think these create form and create modelForm commands are a great idea and second Johan’s point about not wanting a lot of files created. THese commands would give us greater control and convenience.
Hi Mike,
I think you have a point on the admin media setting. But I’d just keep Django the way it is for the rest: it’s creators did some sensible choice and I really hope (as you point out) that they won’t take the “convention over config” or even the DRY principle too far as I believe Rails did.
I find that a slighly more verbose syntax might make things clearer most of the times and implicit conventions go against another Python coding guideline that instead I like to take more at heart “explicit is better than implicit”.
I’ve only recently started playing with Python & Django with any sort of frequency and I can see how this sort of stuff causes problems.
I took the obvious route of putting my forms into a forms.py in the application directory straight off the cuff. I expect that I’ll move it into a forms folder and split them into seprate files as it gets a little bigger as well.
Mutter mutter. http://code.djangoproject.com/ticket/2891 fixes the ’/media/’ woes and jacob goes and marks it as wontfix.
Hello, I like the idea of being able to create a form on skeleton on demand. Thank you
You hit the nail on the head: A larger app template just leads to confusion. Well, I guess this is one of the rare results of my Google summer of code project at http://code.google.com/p/django-package/ (Just ignore django-reusableapps for now): Giving beginners more files at the start of their “project” doesn’t necessarily mean they will understand why they would need all of them. So I agree, there is a problem. But it’s my belief that this should be adressed with proper documentation. Maby just some more NOTE boxes in the documentation that tell about Python zen and best practices.
Your second option is quite interesting, too, but will also start a discussion about what should be automated with django-admin (or better: “django”). It could lead to an unbalance between code generators and actual code.. something which would make beginners to see Django in a somewhat different way than now. I for one would like to see beginners to understand what they are doing (laying practical aspects of a forms.py generator aside for a moment).
I think the idea of different “manage.py startapp” behaviors is great. It gives the power users what they need (and reduces the amount of code they have to delete) and on the other hand offers newbies more hints on where to put things.
I’ve often seen the question about where to put forms (I always tend to have them all in a forms.py module) so giving that as a default might make a lot of sense. Giving a blank-ish urls.py file makes sense, too. I think that’s where things should stop cause the other cases are so special that people dealing with them should by then have realized how things work.
It might make sense to add a few notices to the output of the newbie-friendly startapp variant saying something like: “If your views.py file grows to large or you build a set of helper functions that don’t really seem to belong anywhere, remember that it’s all python and put it into its own module. Readability counts.”
One thing that I feel would be a good default would be to include a tests.py (or, in my case, a tests package) and a templates directory in the default startapp action. Possibly even a base.html with a few standard blocks in it. I end up creating both as soon as I create the application. In the case of the tests.py, a comment saying that doctests in models.py are also usable would be good.
I feel having a default tests.py might be a subtle hint to people that writing tests is both good and easy.
I think the way it is is more then ok… It is simple to start. Newcommers should try the tutorial (wich needs to be updated and expanded) ... Newcommers need to learn to use IRC and the mailing list.
But most important of all Django need more examples… Lots more… And don’t always use python interactive line… It confuses newcommers.
Examples of what you can do with newforms and al sort of aspects… If these are there you could point a newcommer at an example and explain it.
I agree with the general thrust of your post. With your manage.py examples, though, it’s worth thinking about which cases are useful helpers and which are steps down the road of code generation, something Django has (wisely IMO) avoided.
That said, some kind of Paste-style project or app templating seems like a good idea.
I’m pretty new to python/Django, and was brand new to both a few months back … the /media/ thing did confuse me at the start, but if you read the docs it explains what’s recommended and why. Still, it’d be more pleasant if a new user didn’t have to be aware of all the caveats to the default settings. I do like Jacob’s startapp suggestion.
Like Jacob, I’m concerned about finding balance. I’m also concerned about throwing a huge number of files/directories at a complete newcomer and hoping he/she will figure out what all of them are for.
I think that the best option will involve some sort of method of generating different types of app/project skeletons, and whether that belongs in Django itself, in a contrib app or somewhere else is something to debate.
Wow, thank you all for the many comments. It seems like the consensus is that more of these types of helpers could be beneficial, although it’s important to strike a balance. I think Jacob’s idea is a great one. It hits on that balance.
Since I have the Django Command Extensions project on google code (by the way, all are invited to join in) I’ll start playing around with some of these ideas and try to get some feedback from the community.
Experimenters should keep in mind that you can create your own manage.py command easily enough using the technique documented at the very bottom of this page:
http://www.djangoproject.com/documentation/django-admin/
Conventions can be a pretty important learning tool, because many of the capabilities of a framework rely on one file or another being in place. An new Rails application or Visual Studio ASP.NET template give you lots of hints about what the framework does, and how you should implement things.
I didn’t think about this until I learning Django a few months ago, and discovered references to various things that I needed to create spread across several of the (excellent) subject-orientated documentation files. Even now, I’m not totally sure that I’ve structured my site project and applications in the best possible way.
So I’d definitely be really pleased to see anything that says “this is what the Django developers envisage an average application should look like”, whether it’s a command option to generate skeleton files, or just an short overview of “Django anatomy” in a future version of the Django book.
kudos on trying to address this. Keep it lean by asking the 5 why’s of why it isn’t simpler or more obvious. Even you admit media is not obvious. Though Rails is complex, it succeeds because it has pretty simple step by step ways for the new user to quickly start showing results and feeling good about it. Rails 2.0 now even defaults to SQLite so the initial user doesn’t even have to config a database – now that’s simplicity without compromising advanced users from using postgres or mysql. I think good defaults are far more important than more files or templates which might make it simpler but at the expense of complexity. Keep asking PHP users why they aren’t converting though python is a far superior language.
Do not throw in extra django-admin.py commands when they are not needed!
One of the beautiful things about Django is its copious amount of helpful and relevant documentation. Rather than writing some new commands for people to learn, it would more beneficial to write a “Code Organization” piece of documentation. This will allow you to discuss everything from basic newbie level stuff to using separate files for models, creating modular applications, and every other way to organize your code.
This approach points users to the (excellent) Django Docs, and gets them used to searching there first for the information they need.
RockHoward: good point, I should have referenced it. I also have a screencast (http://blog.michaeltrier.com/2007/11/20/django-screencasts-episode-003) that walks you through custom management commands. Plus a cheatsheet available from the show notes.
John: I think it’s awesome that Rails is using sqlite as the default. We get lots of questions surrounding the issue of “I just want to check this thing out but I’m having trouble compiling postgresql.” When I point out to just use sqlite and not think about it, many are surprised. I am really impressed with some of the new stuff in Rails 2.
I second Luke G proposition. I remember my fights with signal connections. The documentation for actually using signals (not the signals per se) is sparse. And the dispatcher and built-in signals are documented only on wiki (shouldn’t this be in main documentation?).
The difference between project and application. This was the most difficult thing to understand. Say you want to create a blog. Is blog your project? It was for me. Now I know your project is rather your site and the blog is your application.
I still miss the right explanation. And, add another explanation from another perspective.