Monday, October 6, 2008

Django From the Ground Up: Episode 11

with host Eric Florenzano

Bookmark and Share

In this episode we update our events app to take advantage of the social networking features that we have built, using some more advanced QuerySet techniques (including one tip by reader janr). I also discover a bug on the live site, and give a preview of how deployment will work.

Yet another way

Originally I wrote code that looks like this in our socialgraph app:

following = [f.to_user for f in UserLink.objects.filter(from_user=user).values('to_user')]
users = User.objects.filter(id__in=following)

Thanks to the advice of janr in the comments, I discovered that it's possible to use the values_list method to make this easier:

following = UserLink.objects.filter(from_user=user).values_list('to_user', flat=True)
users = User.objects.filter(id__in=following)

There's even another approach to this problem, though, and that's to access the query object to ensure that this all happens in one query, via a subquery:

following = UserLink.objects.filter(from_user=user).values('to_user')
users = User.objects.filter(id__in=following.query)

The advantage in the latter method is that it reduces the amount of round trips required between the application layer and the database layer, and the disadvantages are that it potentially offloads more work to the database (depending on how your database engine works), and it requires you to access the semi-internal query variable. Although since the official Django documentation mentions this trick, I think it's quite safe to assume that it will work for quite a while.

  • Running Time: 13:25

Comments - 12 people have already said something. Join the discussion.

  • hardtop said

    Thanks a lot! How can I get first screencasts? Where is no paginator at site.

  • Frank said

    Yeah, I had the same problem a few days ago...
    Just go to http://www.showmedo.org and you'll find all the screencasts.

  • Frank said

    Yeah, I had the same problem a few days ago...
    Just go to http://www.showmedo.org and you'll find all the screencasts.

  • Frank said

    (Sorry about the doublepost)

  • Ulo Pe said

    Hi,

    i was wondering why you are going the .filter(id_in=...) route instead of directly "linking" the models together?

  • Malcolm Tredinnick said

    I hadn't realised that internal API had been documented. It wasn't meant to be exposed, since it's simply not a good API. That's a shame, since we're stuck with it now.

    The idea is that the same functionality should be exposed but you pass in a queryset, not a queryset.query (it avoids having to do the values() call and pick the right field, amongst other things). That will be the case in Django 1.1.

  • Patrick said

    The direct (and correct) URL to the other screencasts:
    http://showmedo.com/videos/series?name=PPN7NA155

  • Eric Florenzano said

    Whoops, looks like the showmedo video wasn't linked correctly. It should be correct now.

    Malcolm: I definitely agree that your proposed API seems cleaner. Can't wait to be able to use that.

  • Stefan said

    This deployment script (fab), is this like Capistrano but for Python?

  • Eric Florenzano said

    Stefan: Yes, it's similar to Capistrano except it's a much simpler tool. Capistrano has support for many things out of the box, and it is really a DSL, whereas Fabric (fab) is just a few python utility commands to write custom scripts which are invoked by a nice command-line tool.

  • Masklinn said

    Eric, would it be possible to at fix the twid screencast feed to use enclosures, so that we could at least subscribe to the screencast in e.g. itunes, even if the screencast serie doesn't show up on the itunes store?

    That would be *really* cool.

    Thanks.

  • Scot Hacker said

    For those trying to find the earlier screencasts in order to traverse the series in order (at least until the site provides a single URL for the series), just search the twid site for "ground" and you'll get them all.

Leave a comment

Please leave your comments below.