views:

123

answers:

1

There's probably an obvious way to do this that I'm missing, so sorry for the noobish question.

I've got models like this:

class Speaker(models.Model):
    name = models.CharField(max_length=50)

class Talk(models.Model):
    title = models.CharField(max_length=50)
    speaker = models.ForeignKey(Speaker)

How can I elegantly get a list of all speakers who've given talks?

At present I'm doing horrible things with getting the list of all Talks and looping through them, because I can't see an easy way of doing it using Django's ORM.

+3  A: 
Speaker.objects.exclude(talk=None)

or

Speaker.objects.filter(talk__isnull=False)

Edit:

Looking at the underlying SQL (by adding .query.as_sql() on the end of the expression), it seems the latter form is significantly more efficient. The former does a completely unnecessary subquery.

I suspect this is a bug, as the first form was introduced in the massive queryset refactor that took place just before version 1.0, and is supposed to be the preferred form.

Daniel Roseman
Out of interest - are there behavioural or performance differences between the two?
Dominic Rodger
Hmm, that's a surprise: see my edit.
Daniel Roseman
@Daniel - looks like this already has a ticket (http://code.djangoproject.com/ticket/10790)
Dominic Rodger
Well spotted. Don't know when it'll get fixed though, as Malcolm doesn't seem to have been as active in Django development recently.
Daniel Roseman