1

我有一个 Django 项目,它有两个模型:Group 和 Person。组可以包含 Person 对象或其他 Group 对象。组不能形成一个循环(即,A 组包含 B 组,B 组包含 A 组),这导致了一个树结构,其中 Person 对象是叶子。

我的问题是 - 如何使用尽可能少的 SQL 查询来计算高级组(如根组)中所有包含的组对象和个人对象?

使用 O(N)(其中 N 是子组数)SQL 查询的简单方法是:

def Group(models.Model):
    name = models.CharField(max_length=150)
    parent_group = models.ForeignKey('self', related_name=child_groups, null=True, blank=True)

    # returns tuple (# of subgroups, # of person objects)
    def count_objects(self):
        count = (self.child_groups.count(), self.people.count())
        for child_group in self.child_groups.all():
            # this adds tuples together ( e.g: (1,2) and (1,2) make (2,4) )
            tuple(map(operator.add, count, child_group.count_objects()))

def Person(models.Model):
    user = models.ForeignKey(User)
    picture = models.ImageSpecField(...)
    group = models.ForeignKey('Group', related_name="people")

有没有办法改善这一点,或者我应该只将这些值存储在 Group 对象中?

4

2 回答 2

1

因此,这是许多其他人已经解决的现有问题。如果您使用的是 Django,请查看: http ://django-mptt.github.com/django-mptt/index.html

于 2012-08-29T03:32:55.800 回答
0
  • 在 Postgres 中,您可以使用递归查询,尽管在 Django 中没有直接支持。

  • 或者,您可以考虑对计数进行非规范化,可能有库可以做到这一点。一个快速的谷歌给了我: http: //pypi.python.org/pypi/django-composition/

  • 如果您必须经常选择相同的值并且它们没有太大变化,您可以尝试缓存它们。

于 2012-08-29T03:38:17.237 回答