Django复合群

2024-05-16 20:32:26 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是我的模型:

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。 我试图根据LocationLaureates进行分组:

[
    {
        "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吗?还有别的办法吗?你知道吗


Tags: nameidappmodelmodelslocationallselect
1条回答
网友
1楼 · 发布于 2024-05-16 20:32:26

你可以这样做:

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文档,遇到类似问题时,我总是去那里:
https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

相关问题 更多 >