如何在Django中使用ManyToMany关系制作过滤注释?

时间:2011-03-19 18:09:45

标签: python django django-models many-to-many

我有一个包含文章,活动和人物的模型:

class Person(models.Model):
  id = models.IntegerField(primary_key=True)
  name = models.CharField(max_length=30)

class Event(models.Model):
  id = models.IntegerField(primary_key=True)
  title = models.CharField(max_length=200)

class Article(models.Model):
  id = models.IntegerField(primary_key=True)
  title = models.CharField(max_length=200)
  publishDate = models.DateTimeField(blank=True, null=True)
  event = models.ForeignKey(Event, blank=False, null=False)
  persons = models.ManyToManyField(Person)

文章属于某个事件,事件由许多文章组成。许多文章和文章中出现的人包含许多人。我们的想法是在给定的时间间隔内查看哪些事件的编写最多。我在一个查询中做到了这一点:

topEvents = Article.objects.filter(publishDate__gt=dateStart)
                           .filter(publishDate__lt=dateEnd)
                           .values('event').annotate(count=Count('id'))
                           .order_by('-count')[:topN]

我发现这比计算前N个服务器端的时间要少得多。

现在,问题是,我如何处理与人员的ManyToMany关系?另外,这是最好的方法吗?

2 个答案:

答案 0 :(得分:5)

简化您的示例:

class Event(models.Model):
    title = models.CharField(max_length=200)

class Person(models.Model):
    name = models.CharField(max_length=30)

class Article(models.Model):
    title = models.CharField(max_length=200)
    publishDate = models.DateTimeField(blank=True, null=True)
    event = models.ForeignKey(Event, related_name='articles')
    persons = models.ManyToManyField(Person, related_name='articles')

请注意,Django自动创建它们时没有id个字段。此外,event类上的personsArticle都将related_name设置为“文章”,这样我们只需使用event.articles和{即可引用文章{1}}。

现在,为了获得最常写的事件和人员,您可以直接在他们的模型经理上查询:

person.articles

答案 1 :(得分:0)

你试过了吗?

topUsers = Article.objects.filter(publishDate__gt=dateStart)
                          .filter(publishDate__lt=dateEnd)
                          .values('persons').annotate(count=Count('id'))
                          .order_by('-count')[:topN]
相关问题