Python Django复合群
以下是我的模型:Python Django复合群,python,django,django-queryset,django-orm,Python,Django,Django Queryset,Django Orm,以下是我的模型: 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() competiti
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。
我试图根据位置对获奖者进行分组
:
[
{
"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
results = []
for location in Location.objects.all():
for competition in location.competition_set.all():
for laurete_competition in competition.laurete_competition_set.all():
results.append(laurete_competition.laurete_set.all())
print results
如果我使用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吗?还有其他方法吗?您可能可以这样做:
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
results = []
for location in Location.objects.all():
for competition in location.competition_set.all():
for laurete_competition in competition.laurete_competition_set.all():
results.append(laurete_competition.laurete_set.all())
print results
还可以看到优秀的Django文档,当我遇到类似问题时,我总是去那里:
在尝试编写匹配的Django ORM代码之前编写SQL可能会有所帮助。一旦您了解了SQL,您就可能知道如何让ORM生成它。我养成了这样做的习惯。此外,它可能取决于您的数据库。您基本上希望从数据库中获取阵列。我知道PostgreSQL和psycopg2可以开箱即用,但我不知道其他数据库。@jpmc26我用SQL表达了它。请检查编辑。我指的是您想要的查询,包括分组依据
。如果您的数据库不能返回数组,那么您就只能像现在这样在Python中执行它。您到底想要什么?你想要每个位置的获奖者名单吗?@rednaw是的。上面的json就是我想要的。