I'm trying to achieve some extra select on a queryset and wants to add the needed table to the pool of tables in the query using the select_related method in order to benefit for the '__' syntax.
Here is an example with simple models :
from django.db import models
# Create your models here.
class testA(models.Model):
code = models.TextField(unique = True)
date = models.DateTimeField(auto_now_add = True)
class testB(models.Model):
text = models.TextField()
a = models.ForeignKey(testA)
And here is the query I want to build :
SELECT (extract(hour from testa.date)) AS hour, testb.text FROM testb INNER JOIN testa ON (testb.a_id = testa.id)
So here is how i build it in python :
testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour','text')
but django removes the select_related when he sees that I'm not using the "testa" table (because of the 'values' statement). So the resulting SQL query fails :
SELECT (extract(hour from testa.date)) AS "hour", "testb"."text" FROM "testb"
If I remove the "values" statement it works fine :
SELECT (extract(hour from testa.date)) AS "hour", "testb"."id", "testb"."text", "testb"."a_id", "testa"."id", "testa"."code", "testa"."date" FROM "testb" INNER JOIN "testa" ON ("testb"."a_id" = "testa"."id")
but I must put the values statement as I want to make aggregates as in "count the b objects grouped by the hour of the date in the a object" :
testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour').annotate(count = Count('pk'))
So what is the good way to achive this ? "Count objects grouped by something in another object" ? Or is there a way to "force" django to keep the "select_related" tables even if he thinks they are useless ?
PS : I know I could use the "tables" argument of the extra statement but in that case I would have to rewrite the join by myself and I want to benefit from the django ORM