与看起来似乎有点挣扎应该是一个简单的问题......
基本上我有一些网站会在几年内发生对象计数:
示例:
site_id = Site1: (Year:2012,Count:133), (Year:2011, Count:150), (Year:2010, Count :110)
site_id = Site2: (Year:2010, Count:300), (Year:2010, Count 333)
数据暂时不完整(不规律 - 某些网站被计算了几年......其他网站没有......)..而且,有时这些地方每年都被计算几次
我想要做的是获得每个网站的最新计数,如果有多个计数,我想获得最高计数。 然后我想在HTML中显示它。
这是我的MODELS.PY
class Counts(models.Model):
count_id = models.AutoField(primary_key=True)
site = models.ForeignKey('Site', blank=True, null=True)
year = models.IntegerField(blank=True, null=True)
count = models.FloatField(blank=True, null=True)
class Meta:
db_table = 'counts'
class Site(models.Model):
site_id = models.TextField(primary_key=True)
site_code = models.TextField(blank=True, null=True)
site_name = models.TextField(blank=True, null=True)
class Meta:
db_table = 'site'
这是我试图在VIEWS.PY中使用的查询
p = ['Site1','Site2'] ## Just for reference for the example... values come from a POST or a GET
A = Site.objects.filter(site_id__in = p).annotate(latest=Max('counts__year'))
context = RequestContext(request, {'dat':A})
template = loader.get_template('styles/searchResults.html')
return HttpResponse(template.render(context))
以上只给我最近几年:
[{'site_id': u'Site1','latest': 2012}, {'site_id': u'Site2','latest': 2010}]
我想要的是:
[{'site_id': u'Site1','latest': 2012,'count':133}, {'site_id': u'Site2','latest': 2010,'count':333}]
但是 - 我希望它作为QuerySet(而不是ValuesQuerySet),因为我想在我的HTML模板中引用它,如下所示:
<table>
{% for x in dat %}
<tr><td>{{x.count|floatformat}}</td><td>{{x.year}}</tr>
{%endfor%}
</table>
我尝试了以下(在从上面创建A之后): B = Counts.objects.filter(year__in = A.values('latest'),site__site_id__in = p).annotate(site_code = Max('site__site_id'))
但这实际上导致:
[{'site_id': u'Site1','latest': 2012,'count':133},{'site_id': u'Site1','latest': 2010,'count':110}, {'site_id': u'Site2','latest': 2010,'count':333},{'site_id': u'Site2','latest': 2010,'count':300}]
换句话说,它正在为两个站点提取YEAR = 2010或2012的所有值。
同样,我正在寻找的是LATEST year. Max(count), Max(year)
的最高分数 - 我确信它会以某种方式播放......
谢谢!
答案 0 :(得分:2)
如何按年份排序并计算并使用.distinct()仅获取每个站点的第一条记录?
A = Counts.objects.filter(site_id__in = p).order_by('site_id','-year','-count').distinct('site_id')
如果您需要相应的网站信息,可以在模板
中访问<table>
{% for x in dat %}
<tr><td>{{x.count|floatformat}}</td><td>{{x.year}}</td><td>{{x.site.site_name}}</td></tr>
{%endfor%}
</table>
或使用.values()指定视图中每个模型所需的值。结果 也可以在模板中迭代。
答案 1 :(得分:1)
编辑:
虽然以下答案对我有用,但我对表现感到担忧...... 所以我根据用户5219763进行了重新调整 - 现在更干净了......
我已经修好了,发现这个有用......
from itertools import chain
### First create an empty list to push querysets
qlist = []
### Iterate through each selected ID
for x in p:
### Find the value for the latest year for each site id selected
A = Site.objects.filter(site_id = x).aggregate(Max('counts__year'))['counts__year__max']
if A:
### Find value of the highest count for year identified above for the selected site
B = Counts.objects.filter(year = A, site__site_id=x).aggregate(Max('count'))['count__max']
### Now, resample the Site where the year is the max and count is max, then annotate the queryset
### with the values from year and count in the Counts table...
C = Site.objects.filter(counts__year=A,counts__count=B).annotate(year = Max('counts__year'), count = Max('counts__count'))
### push this query to the list
qlist.append(C)
else:
continue
### use itertools chain command to merge these into a single queryset
qs = list(chain.from_iterable(qlist))
击> <击> 撞击>
现在我正在使用:
qs = Counts.objects.filter(site__site_id__in = p).order_by('site__site_id','-year','-count').distinct('site__site_id').select_related()
然后,在我的HTML中,我这样引用它:
{% for x in dat %}
<tr ><td>{{ x.site.site_name }}</td><td>{{x.site.site_code}}</td><td>{{x.count|floatformat}}</td><td>{{x.year}}</td></tr>
{% endfor %}
谢谢,伙计们!
答案 2 :(得分:0)
QuerySet
和ValuesQuerySet
有两种解决方案。
<强> 1。查询集强>
不推荐用于大型Site
和Counts
表,因为性能 - 对于每个站点,您将获得另一个查询来获取Counts
的最新对象(复杂度{{ 1}})。但如果行数很少,那就没问题了。例如:
视图的
O(N*M)
模板的
A = Site.objects.filter(site_id__in=p).annotate(latest=Max('counts_set__year'))
# Fetch latest Counts for each Site object
for site in A:
site.counts_latest = site.counts_set.order_by('-year').first()
这就是全部!
<强> 2。 ValuesQuerySet 强>
您应该在<table>
{% for x in dat %}
<tr>
<td>{{x.counts_latest.count|floatformat}}</td>
<td>{{x.counts_latest.year}}</td>
</tr>
{%endfor%}
</table>
列出所有values
字段,这些字段可以在模板中使用。例如:
视图的
Counts
模板的
A = Site.objects.values('counts_set__count', 'counts_set__year') \
.filter(site_id__in=p).annotate(latest=Max('counts_set__year'))
希望这有帮助!