我正在创建一个人们可以为城市发帖的应用。我想为国家/地区创建一个视图,其中会显示有海报的城市列表,以及为每个城市制作的海报数量。
我有一个国家/地区表和一个带有国家/地区外键的City表。我还有一张海报表,其中包含City表的外键。
这成功地给了我一份海报清单,但是如何将它们分组到城市并通过呢?在模板中,我希望能够显示该城市中的城市名称,poster.image,以及该城市中每个海报的海报总数。
def country_page(request, country_name):
country = get_object_or_404(Country, name__iexact=country_name)
posters = Poster.objects.filter(city__country=country)
variables = RequestContext(request, {
'location' : country,
'posters' : posters,
})
return render_to_response('country_page.html', variables)
任何帮助将不胜感激。
答案 0 :(得分:0)
在原始sql中,你可以使用" group by"等等,但对于django,你应该研究模型的聚合函数。
https://docs.djangoproject.com/en/dev/topics/db/aggregation/
几天前我遇到了类似的问题,这就是我如何解决它的问题。首先从特定条件中过滤对象,然后指定所需的字段,最后进行计数,以了解总行数。
您的解决方案可能看起来像这样:
posters = Poster.objects.filter(city__country=country).values('city_name','poster_image',..).annotate(total=Count('city'))
答案 1 :(得分:0)
这也可以通过代码而不是所有SQL来实现,但考虑到应用程序的性质 - 许多城市可能会有很多海报 - 这种解决方案很容易占用太多的系统资源。但这是一个快速片段:
key = lambda poster: poster.city
posters = Poster.objects.filter(city__country=country)
posters = sorted(posters, key=key)
di = {}
for k, g in itertools.groupby(posters, key):
di[k] = list(g)
现在di
将每个城市包含为关键字,并将所有海报列表作为值。
答案 2 :(得分:0)
你正在寻找的是sql land中的'group by'。
下面的帖子有一些有趣的见解,底线是你需要原始的sql做一个真正的组,但我怀疑你的需求你可以只做一点后处理来进行分组:
posters = Poster.objects.filter(city__country=country)
poster_cities = {}
for poster in posters:
if city not in poster_cities:
poster_cities[city] = []
poster_cities[city].append(poster)
现在你可以按照这样的城市获取海报,从模板中使用:
for city in sorted(poster_cities.keys()):
city_posters = poster_cities[city]
city_poster_count = len(poster_cities[city])
背景:
答案 3 :(得分:0)
这将返回城市,每个城市都包含该城市的海报数量:
cities = City.objects.filter(country=my_country).annotate(num_posters=Count('posters'))
然后你可以在模板中循环:
<h1>{{ country }}</h1>
{% for city in cities %}
<p>
{{ city.name }} - {{ city.num_posters }} posters
{% for poster in city.posters.all %}
<img src="{{ poster.image.url }}">
{% endfor %}
</p>
{% endfor %}
现在,上面的代码分别为每个城市提取海报,这可能效率不高。要解决这个问题,您可以使用prefetch_related(如果您能负担得起使用Django主干),也可以自己手动执行,例如here
答案 4 :(得分:0)
使用您已有的代码,您可以在模板中使用regroup,例如:
{% regroup posters by city as city_list %}
<ul>
{% for city in city_list %}
<li>{{ city.grouper }} ({{city.list|length}})
<ul>
{% for poster in city.list %}
<li>{{ poster.image}}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
请注意,您需要在视图中按城市订购海报查询。