Tubecaster 3 UI Mockup
Here’s a mockup of the main window for the upcoming Tubecaster 3. The release will include support for multiple downloads at once, playlist download support and built-in media conversion tools. Stay tuned!

Geek
Here’s a mockup of the main window for the upcoming Tubecaster 3. The release will include support for multiple downloads at once, playlist download support and built-in media conversion tools. Stay tuned!

I just had a situation where I was trying to filter the queryset for a ModelMultipleChoiceField based on the currently logged-on user. I was going crazy trawling through the Django docs and eventually Google. It seemed like something which should be so simple, but there was no obvious way to do it. Eventually I found the answer, and it IS simple! As an example, let’s say you have the following two models as part of a simple photo gallery app:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Photo(Model): name = CharField(max_length=100) caption = CharField(max_length = 150) user = ForeignKey(User) upload_timestamp = DateTimeField(auto_now_add=True) image = ImageField(upload_to="user_images/%Y/%m/%d/") thumbnail = ImageField(upload_to="user_images/%Y/%m/%d") def __unicode__(self): return self.name class Album(Model): name = CharField(max_length=100) caption = CharField(max_length = 150) user = ForeignKey(User) photos = ManyToManyField(Photo, related_name="albums", blank=True) creation_timestamp = DateTimeField(auto_now_add=True) cover_photo = ForeignKey(Photo, related_name="cover_photos") def __unicode__(self): return self.name |
We then define a ModelForm based on the Album model, which allows users to create albums with photos they’ve previously uploaded (pretend we’ve already made that possible). We only expose the “name”, “caption” and “photos” fields because we’ll fill in the others automatically as part of our view:
1 2 3 4 | class AlbumCreationForm(ModelForm): class Meta: model = Album fields = ("name", "caption", "photos") |
Now here’s the real magic. Ordinarily, when first showing the form (pre-POST) we would create it like this and pass it to the template:
form = AlbumCreationForm() |
The problem here is that by default we’ll get all photo objects, i.e. the result of “Photo.objects.all()”. That’s a problem because in this case we just want to list the photos belonging to the current user. To do this, just add the following line:
form.fields["photos"].queryset = Photo.objects.filter(user=request.user) |
It turns out that form fields can be accessed as a dictionary attached to the form instance, and that if the field is model-related, like “photos” in the example, you can update its queryset dynamically.
Here’s a partial view which uses the last two code samples, to provide some context:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def create_album(request): if request.method == "POST": # Process form. else: form = AlbumCreationForm() # Get just the photos belonging to this user. form.fields["photos"].queryset = Photo.objects.filter(user=request.user) template_vars = RequestContext(request, { "form": form, "user": request.user }) return render_to_response("create_album.html", template_vars) |
That’s it! Adding the one extra line to the view gives us the filtering we need.
One of my passions has always been the articulate expression of oneself through language. We have this wonderful, rich language we call English and there is great joy to be found in learning to use it effectively. The point of this post isn’t to rant about the degradation of the language or our frequent abuse of it – I’ve covered that already – instead, I’d just like to talk about different ways of using the language in different contexts, and that I believe it doesn’t make sense to enforce strict, blanket rules across the board.
Spoken language
With the possible exception of presenting a formal talk or making a speech, I don’t believe we should be pedantic about spoken language. People are all raised in different environments and have acquired their knowledge and techniques of language usage in different ways. Everyone’s thought patterns also differ widely and speech is our way of converting those thoughts into a form that we can share with others. I will never correct someone’s spoken language under any circumstances. We need to respect each individual’s way of expressing themselves.
Written language
This is really the core of knowledge transfer and has formed the basis for accurate handing down of knowledge through the ages. Thanks to the digital age this might change to include new mediums such as video, but for now we all still write a tremendous amount in various forms.
Attention to detail and careful thought are required to make sure that our thoughts are interpreted to the reader as clearly as we perceive them in our heads. Even when writing a simple email there is something about sending away a piece of writing, to be read at the receiver’s leasure, that forces us to be more broad and accomodating with our choice of wording and sentence structure. We are never quite sure what mood or state of mind the reader may be in when they read it. Often we may never even have met the person. This is vastly different to spoken language because when we’re speaking to someone, or even to a group of people, we can update our attitude and try different approaches in real time.
Text messaging, instant messaging, and services like Twitter technically form part of written language but based on their semi-live nature I treat them the same as spoken language. I can’t help but still make at least a half decent attempt at proper spelling and grammar, but I don’t mind how casual people want to be as long as they’re able to get their point across.
Remember, the reason we have language is for communication. As long as we can get our point across clearly and effectively then I think we’re doing just fine.
I’ve used Django for a few small projects in the last year and have absolutely fallen in love with it. While I always insist that I’m not a language or framework zealot I will quite happily and unashamedly push the Python / Django team wherever possible. Here are some of the reasons why.
Pythonic. This is a term that has evolved with Python to basically mean compliance with the Zen of Python. Here is the Zen of Python in its entirety as provided by Python.org:
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
It just so happens that this aligns perfectly with the way I think. This is what drew me so quickly and intimately to Python itself. It’s one of those things that makes a language “feel right” to us. Every time I read the Zen of Python I find myself nodding profusely and grinning cheekily. Django is Pythonic.
No black magic. Django’s components provide everything you need, but don’t go away and do anything so mystical that you can’t quickly get a handle on what’s going on and what their thought process may be.
Fantastic, complete documentation. The documentation on the Django website is well-written, complete and up to date with abundant code examples. I really can’t stress the importance of this enough. Anyone who has spent hours trawling through useless, incoherent, incomplete documentation will immediately see the value in this.
It’s ready when it’s ready. The Django developers are not afraid of holding back on a release if it’s not ready. Django 1.1 was released about 3 months later than it was intended and the developers had no shame in holding it back because it wasn’t quite ready. I highly respect them for this because it means that we can fully trust new releases to be very stable with copious amounts of polish.
Stays out of the way. One of the things I respect most about Django is that it doesn’t get in your way. While it provides a complete stack for everything from data model handling to view templates you are free to substitute components with any of your own. Don’t like the built-in authentication mechanism? No problem. Plug in another one or write your own. Django’s concept of “applications” (basically pluggable modules) makes this easy. Want to use your own file storage mechanism instead of what Django provides? You’re more than welcome.
Built-in caching. Django was designed from the ground up with caching in mind and not only provides its own caching mechanisms but also plugs into existing, tried-and-true caching mechanisms like memcached (used by Facebook).
Easy admin interfaces. Django comes with a fully customisable admin interface for your projects which will hook directly into your data models. This allows you to concentrate on developing your end user views without having to first get data entry forms in place. Of course there’s no reason why you can’t continue to use the built-in admin tools or allow portions of them to be used by your end users.
Sane templates. Django’s templating system is just plain sexy. It’s got the lot: fully-featured tags, batteries-included filters, and very simple, Pythonic, easy-to-learn syntax.
I could go on. Apart from all that I’ve just mentioned, Django is also backed by Google and has the stamp of approval from Python’s creator himself, Guido von Rossum.
Not convinced? Just take a look at the vast array of sites being created every day on djangosites.org.
Have you ever been in the situation where you’ve updated your CSS file but users’ web browsers haven’t automatically loaded the new one? The reason is because many web browsers cache the stylesheet for faster future reloading. Obviously you don’t want to have to get your users to Ctrl-F5 every time you update your stylesheet so here’s a little tip for making this automatic in your Django templates.
Let’s say you have a template with the following line:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css" /> |
Every time the page loads the browser cache will think it’s seen the file before and reload the cached version from disk. One solution is to dynamically generate the link so that the browser thinks it is loading a new file every time. One way to do this without actually making a new file every time (you could just rename your CSS file every time you update it, but that’s painful) is to pretend you’re passing some parameters to the CSS file, like this:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?12345" /> |
The trick is to generate a new fake parameter every time the page loads. Django templates make this easy by allowing us to generate a Unix timestamp (the number of seconds since a specific point in history) which we can attach to our link.
To do this we use the “now” template tag. In your template file, update the stylesheet line to the following:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?{% now "U" %}" /> |
This will generate a line like the following every time the page is loaded:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?1249948982" /> |
Voila! Automatically-refreshing stylesheets. You don’t have to make any changes to your stylesheet to use this.
This is a little inefficient, and if you have a super busy site and a very big stylesheet this could add an extra fair bit of bandwidth usage to your server(s). To get around this you could just change the “now” tag usage to generate a daily stamp (see the “now” tag docs), e.g. style.css?20090712, in which case the client browser should only reload it once per day.