Nik*_*ola 1 python django many-to-many django-models
我有一个包含文章,活动和人物的模型:
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)
Run Code Online (Sandbox Code Playgroud)
一篇文章属于一个事件,事件由许多文章组成.许多文章和文章中出现的人包含许多人.我们的想法是在给定的时间间隔内查看哪些事件最多.我在一个查询中做到了这一点:
topEvents = Article.objects.filter(publishDate__gt=dateStart)
.filter(publishDate__lt=dateEnd)
.values('event').annotate(count=Count('id'))
.order_by('-count')[:topN]
Run Code Online (Sandbox Code Playgroud)
我发现这比计算前N个服务器端要少得多.
现在,问题是,我如何处理与人类的ManyToMany关系?另外,这是最好的方法吗?
为了简化您的示例:
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')
Run Code Online (Sandbox Code Playgroud)
请注意,没有id字段,因为Django会自动创建它们.此外,双方event并persons在Article课堂上所related_name设置为"文章",这让我们简单地用指文章event.articles和person.articles.
现在,为了获得最常写的事件和人员,您可以直接在他们的模型管理器上查询:
Event.objects.filter(articles__publishDate__gt=dateStart)\
.filter(articles__publishDate__lt=dateEnd)\
.annotate(count=Count('articles')).order_by('-count')
Person.objects.filter(articles__publishDate__gt=dateStart)\
.filter(articles__publishDate__lt=dateEnd)\
.annotate(count=Count('articles')).order_by('-count')
Run Code Online (Sandbox Code Playgroud)