I just wanted to try to build a project with django. Therefore I have a (basic) question on how to manage such a project. Since I cannot find any guidelines or so on how to split a project into applications.

Let's take a kind of SO as an example. Which applications would you use?
I'd say there should be the applications "users" and "questions". But what if there was a topic system with static articles, too. Maybe they also could receive votes.
How to build the apps structure then? One app for "questions", "votes" and "topics" or just one app "content"?

I have no idea what to do. Maybe it's because I know not very much about Django yet, but I'm interested either...

6 Answers
6

There aren't hard-and-fast rules, but I would say it's better to err on the side of more specialized applications. Ideally an application should handle just one functional concern: i.e. "tagging" or "commenting" or "auth/auth" or "posts." This type of design will also help you reuse available open source applications instead of reinventing the wheel (i.e. Django comes with auth and comments apps, django-tagging or django-taggable can almost certainly do what you need, etc).

Generic foreign keys can help you decouple applications such as tagging or commenting that might be applied to models from several other applications.

You should try and separate the project in as much applications as possible. For most projects an application will not contain more than 5 models. For example a project like SO would have separate applications for UsersProfiles, Questions, Tags (there's a ready one in django for this), etc. If there was a system with static pages that'd be a separate application too (there are ready ones for this purpose). You should also try and make your applications as generic as possible, so you may reuse them in other projects. There's a good presentation on reusable apps.

Just like any set of dependencies... try to find the most useful stand-alone aspects of the project and make those stand-alone apps. Other Django Apps will have higher level functionality, and reuse the parts of the lowest level apps that you have set up.

In my project, I have a calendar app with its own Event object in its models. I also have a carpool database set up, and for the departure time and the duration I use the calendar's Event object right in my RideShare tables. The carpooling database is calendar-aware, and gets all the nice .ics export and calendar views from the calendar app for 'free.'

There are some tricks to getting the Apps reusable, like naming the templates directory: project/app2/templates/app2/index.html. This lets you refer to app2/index.html from any other app, and get the right template. I picked that one up looking at the built-in reusable apps in Django itself. Pinax is a bit of a monster size-wise but it also demonstrates a nice reusable App structure.

If in doubt, forget about reusable apps for now. Put all your messages and polls in one app and get through one rev. You'll discover during the process what steps feel unnecessary, and could be broken out as something stand-alone in the future.

A good question to ask yourself when deciding whether or not to write an app is "could I use this in another project?". If you think you could, then consider what it would take to make the application as independent as possible; How can you reduce the dependancies so that the app doesn't rely on anything specific to a particular project.

Some of the ways you can do this are:

Giving each app its own urls.py

Allowing model types to be passed in as parameters rather than explicitly declaring what models are used in your views. Generic views use this principle.

Make your templates easily overridden by having some sort of template_name parameter passed in your urls.py

Make sure you can do reverse url lookups with your objects and views. This means naming your views in the urls.py and creating get_absolute_url methods on your models.

In some cases like Tagging, GenericForeignKeys can be used to associate a model in your app to any other model, regardless of whether it has ForeignKeys "looking back" at it.

I'll tell you how I am approaching such question: I usually sit with a sheet of paper and draw the boxes (functionalities) and arrows (interdependencies between functionalities). I am sure there are methodologies or other things that could help you, but my approach usually works for me (YMMV, of course).