08Sep

Small but useful Django notions…

Posted by Elf Sternberg as django, web development

If you’ve created Django Application A, and then Django Application B, it is acceptable (and even sometimes necessary) for Application B to reference Application A.  The canonical example is Django contrib.auth; everyone references that beast.  It is not acceptable for you to go and edit Application A to reference Application B.  That is officially Doin’ It Wrong.

In a smarter world, you will never use a Django ManyToMany field.  You will create an individual class referencing both objects of the many-to-many relationship.  You will inevitably need more smarts than a mere two-column table, and a separate class, however small and insignificant, will provide both self-documentation and a chance to define the __unicode__() method for administration. Django is smart enough to hook up the relationships under the hood.

Unit testing is goddamned hard when your application is married to FacebookConnect.  A smarter relationship uses the SocialAuth layer, with additional proxies for information and posting handlers.  That way, not only can your application send updates to Facebook walls, but it can also update its activity on Twitter, and allow authentication via Google, and so on.  By using the SocialAuth layer, you can create a pseudo-layer that handles testing.  You’re still beholding to testing the SocialAuth stuff yourself.

If you’re using SocialAuth, push all of your user-related smarts into the UserProfile object, and always refer to it.  Build your UserProfile object to own the proxy to the user’s authenticated relationships with social media.  After login, leave the user alone!  Better yet, use middleware to attach the profile to the request object automagically if and when it’s present, and live with it.

2 Responses to Small but useful Django notions…

Pedro Costa

September 9th, 2009 at 2:06 am

Why not use ManyToMany field? Why not using the “through” parameter and do exactly what you say?

http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

Elf Sternberg

September 9th, 2009 at 5:49 am

Because then you’re repeating yourself, and violating DRY.

If you create a model X with foreign keys for both your model A and model B, Django will automatically decorate instances of either model with reference managers pointing back to collections of the other model in a Many-to-many relationship through X. Since Django sets that up at init, why do you then need to go specify either relationship in either model?

Also, look at my first point about creating circular dependencies in Django model design. With rare exceptions, a well-designed Django project will have several silos of independent applications. Many-to-many relationships between the applications may exist in a dependent relationship (one app must know about the other) or in an independent relationship (both applications can exist separately, but a many-to-many relationship between the models of each applications gives the developer greater expressive power). In the latter, the Many-to-many relationship should be written into a third application independent of both. The developer knows, inside his third application, that A “knows” about B through X, and B “knows” about A through X, and the syntax of A referring to B and vice versa are all there as expected, without having to clutter either A or B with excess knowledge about X.

Comment Form

Subscribe to Feed

Categories

Calendar

September 2009
M T W T F S S
« Aug   Oct »
 123456
78910111213
14151617181920
21222324252627
282930