【发布时间】:2014-01-27 17:14:26
【问题描述】:
这是我的模型:
class Location(models.Model):
city = models.CharField()
class Competition(models.Model):
name = models.CharField()
location = models.ForeignKey(Location)
class Laureate(models.Model):
name = models.CharField()
competitions = models.ManyToManyField(Competition, through='LaureateCompetition')
class LaureateCompetition(models.Model):
laureate = models.ForeignKey(Laureate)
competition = models.ForeignKey(Competition)
我正在使用 PostgreSQL。
我正在尝试根据Location 对Laureates 进行分组:
[
{
"city": "Moscow",
"laureates" : ["Bob", "Peter", "Maria"]
},
{
"city": "London",
"laureates" : ["Nicolai", "John", "Adam"]
}
]
我最终做的是这样的:
locations = []
all_laureate_competitions = LaureateCompetition.objects.select_related().all()
all_competitions = Competition.objects.order_by('location')\
.distinct('location')\
.select_related()
for competition in list(all_competitions):
location = competition.location
competitions = list(set(
[x for x in all_laureate_competitions
if x.competition.location == location]
))
laureates = list(set([x.name for x in competitions]))
locations.append(create_location(location, laureates))
return locations
如果我用 SQL 来做:
SELECT app_location.country,
(SELECT array
( SELECT DISTINCT ON (app_laureate.name) app_laureate.name
FROM app_laureatecompetition
LEFT JOIN app_laureate ON app_laureate.id = app_laureatecompetition.laureate_id
WHERE app_laureatecompetition.competition_id IN
(SELECT app_competition.id
FROM app_competition
WHERE app_location.id = app_competition.location_id) )) AS pupils
FROM app_location
我不太喜欢第一种方法。 进行此类查询的常见做法是什么?我应该用原始sql来做吗?还有更多的orm方式吗?
【问题讨论】:
-
在尝试编写匹配的 Django ORM 代码之前编写 SQL 可能会有所帮助。一旦您了解了 SQL,您可能会弄清楚如何让 ORM 生成它。我养成了这样做的习惯。此外,它可能取决于您的数据库。您基本上想从数据库中取回数组。我知道 PostgreSQL 和 psycopg2 可以开箱即用,但我不知道其他数据库。
-
@jpmc26 我用 SQL 表示。请检查编辑。
-
我的意思是你想要的查询,包括
GROUP BY。如果你的数据库不能返回一个数组,那么你就只能像现在这样在 Python 中进行操作了。 -
你到底想要什么?您想要每个地点的获奖者名单吗?
-
@rednaw 是的。上面的json就是我想要的。
标签: python django django-queryset django-orm