问题
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
回答1:
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')
回答2:
The following view amalgamates two queries to solve the problem,
def info(request):
info_model = InfoModel.objects.values('topic')
.annotate( max=Max('date'),
freq=Count('postid'),
contributors=Count('author', distinct=True))
.order_by('-max')
info2 = InfoModel.objects.all()
columnlist = []
for item in info2:
columnlist.append([item])
for item in info_model:
for i in range(len(columnlist)):
if item['max'] == columnlist[i][0].date:
item['author'] = columnlist[i][0].author
item['post'] = columnlist[i][0].post
return render(request, 'info.html', {'info_model': info_model})
来源:https://stackoverflow.com/questions/37901376/rewrite-raw-sql-as-django-query