Search code examples
djangodjango-querysetrawsql

Rewrite raw SQL as Django query


I am trying to write this raw SQL query,

info_model = list(InfoModel.objects.raw('SELECT *, 
              max(date),  
              count(postid) AS freq,     
              count(DISTINCT author) AS contributors FROM        
              crudapp_infomodel GROUP BY topicid ORDER BY date DESC'))

as a django query. The following attempt does not work as I can't get related fields for 'author' and 'post'.

  info_model = InfoModel.objects.values('topic')
                 .annotate( max=Max('date'), 
                  freq=Count('postid'),              
                  contributors=Count('author', 
                  distinct=True))
                  .order_by('-max')

With raw SQL I can use SELECT * but how can I do the equivalent with the Django query?

The model is,

class InfoModel(models.Model):
    topicid = models.IntegerField(default=0)
    postid = models.IntegerField(default=0)
    author = models.CharField(max_length=30)
    post = models.CharField(max_length=30)
    date = models.DateTimeField('date published')

I did previously post this problem here Django Using order_by with .annotate() and getting related field


Solution

  • I guess you want to order by the maximum date so:

    InfoModel.objects.values('topic')
                     .annotate(
                         max=Max('date'), freq=Count('postid'),              
                         contributors=Count('author', distinct=True))
                     .order_by('max')