我有一个Django项目有两个模型:Group和Person。组可以包含Person对象或其他Group对象。组不能形成一个循环(即包含组B的组A包含组A),这导致一个树结构,其中Person对象是叶子。
我的问题是 - 如何在尽可能少的SQL查询中计算高级组(如根组)中所有包含的Group对象和Person对象?
使用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对象中?
答案 0 :(得分:1)
所以这是许多其他人已经解决的现有问题。如果您正在使用Django,请查看以下内容: http://django-mptt.github.com/django-mptt/index.html
答案 1 :(得分:0)
在Postgres中,您可以使用recursive个查询,但Django中没有直接支持。
或者您可以考虑对计数进行非规范化,可能有库来执行此操作。一个快速的谷歌给了我:http://pypi.python.org/pypi/django-composition/
如果你必须经常选择相同的值并且它们没有那么大的变化,你可以尝试缓存它们。