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就是我想要的。