【问题标题】:Django complex groupingDjango 复杂分组
【发布时间】: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。 我正在尝试根据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来做吗?还有更多的orm方式吗?

【问题讨论】:

  • 在尝试编写匹配的 Django ORM 代码之前编写 SQL 可能会有所帮助。一旦您了解了 SQL,您可能会弄清楚如何让 ORM 生成它。我养成了这样做的习惯。此外,它可能取决于您的数据库。您基本上想从数据库中取回数组。我知道 PostgreSQL 和 psycopg2 可以开箱即用,但我不知道其他数据库。
  • @jpmc26 我用 SQL 表示。请检查编辑。
  • 我的意思是你想要的查询,包括GROUP BY。如果你的数据库不能返回一个数组,那么你就只能像现在这样在 Python 中进行操作了。
  • 你到底想要什么?您想要每个地点的获奖者名单吗?
  • @rednaw 是的。上面的json就是我想要的。

标签: python django django-queryset django-orm


【解决方案1】:

你可能可以这样做:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多