I'm sorry, you are right, I should have provided them. Let me formulate the question again, but with a complete example.
# models.py
class Book(models.Model):
added_date = models.DateField() # date it was added to my shelf
published_date = models.DateField() # date it was published
authors = models.ManyToManyField('Author', related_name='all_books') # a book can have more than 1 author
class Author(models.Model):
name = models.CharField(max_length=100)
#fixture.json
[
{
"model": "main.Author",
"pk": 1,
"fields": {
"name": "John 1"
}
},
{
"model": "main.Author",
"pk": 2,
"fields": {
"name": "John 2"
}
},
{
"model": "main.Book",
"pk": 1,
"fields": {
"added_date": "2000-01-01",
"published_date": "1999-12-31",
"authors": [1]
}
},
{
"model": "main.Book",
"pk": 1,
"fields": {
"added_date": "2000-01-02",
"published_date": "1999-12-31",
"authors": [1, 2]
}
}
]
Notice that book 1 has 1 author, and it took 1 day to add to the shelf. Book 2 has 2 authors, and took 2 days to add.
The average delay between publishing and adding is thus, for each author,
John 1: 1.5 days # (1 day + 2 days)/2
John 2: 1 day.
I'm trying to query authors with the average delay annotated, and ordered by it.
Notice that the average of the difference is the difference of the average and thus,
I can write a query to average each date, and compute the difference of the averages. This is how I'm doing it:
# inside a view.
d = Author.objects.annotate(first_date=Avg('all_books__published_date'),
last_date=Avg('all_books__added_date')) \
.extra(select = {'average_delay': 'last_date - first_date'}, order_by=['-average_delay'])
print d # to evaluate query
In a clean installation of Django, with sqlite3, with the models and fixture I provide here, I get a No such column: last_date error.
If I remove the .extra, this query works (but doesn't give the result I want).
Comment: I find strange that I'm not able to select "last_date" in the extra().
In this question, this problem is addressed. The accepted solution is using
d = Author.objects.extra({'average_delay': 'AVG(all_books__added_date) - AVG(all_books__published_date)'})
print d
In my setup, this gives: no such column: all_books__published_date
Question: What am I missing?
Cheers,
Jorge