我正在开发一个大型Django应用程序,特别是它发送许多电子邮件,然后收集有关它们的信息。我有两个模型通过第三个模型相互关联:
SendEvent是我成功发送任意数量电子邮件时捕获的模型 - 它会记录一些与问题无关的数据。
SentEmail是中间表。它包含对SendEvent的外键引用,名为sendevent,以及一些其他额外信息。
然后我有一个名为EmailEvents的模型,该模型正在侦听我使用的第三方邮件应用程序中的某些webhook,并存储有关收件人正在对我的电子邮件进行操作的信息。此模型包含对SentEmail对象的外键引用。有几个EmailEvent将与单个SentEmail关联 - 最相关的是发送的'并且'打开' (当发送电子邮件时,生成的事件将被生成并记录在EmailEvents表中,并通过唯一的id字符串与SentEmail相关联。与open事件类似,除了它是在收件人打开电子邮件时生成的,显然)。事件类型作为字符串存储在名为event的字段中。
我尝试编写一个查询,在给定SendEvent的情况下,它将为我提供不同类型的关联EmailEvents的计数。
到目前为止,我已经解决了以下问题(send_event是包含对相关SendEvent的引用的变量):
email_events = EmailEvents.objects.filter(sent_mail__sendevent = sent_event)
我相信这将获取所有正确的EmailEvent对象(与给定SendEvent关联的SentEmails关联的对象)。然后我可以在其末尾添加.count()并获取所有EmailEvent的计数。但是,我真正想要的是将其分解为不同类型的EmailEvent。我可以通过循环遍历QuerySet来手动执行此操作,但我预计EmailEvents表会变得非常大,所以我非常希望让ORM为我做这个提升。我如何按事件分组?
我可以吗
EmailEvents.objects.filter(sent_mail__sendevent = sent_event).annotate(Count('event'))
这是最好的方法吗?这会起作用吗?任何建议都会非常感激 - 我在处理大量数据方面有点新意。
答案 0 :(得分:0)
我不确定Django ORM是否有一种简单的方法可以满足您的需求,但您始终可以使用原始SQL - https://docs.djangoproject.com/en/1.7/topics/db/sql/
原始SQL将类似于以下内容(我正在猜测您的表将被调用,但查询基本上如下所示):
select count(distinct(e.event)) from EmailEvents as e, SentEvent where EmailEvent.id = SentEvent.id
答案 1 :(得分:0)
这可以通过将objects.values与annotate一起使用来实现。这是一个样本模型+测试。
首先在models.py
中class Foo(models.Model):
action_type = models.CharField(max_length=50)
然后在tests.py
中from django.test import TestCase
from django.db.models import Count
from foo.models import Foo
class MyTestCase(TestCase):
def test_group_query(self):
options = ('created', 'deleted', 'updated')
for i in range(32):
Foo.objects.create(
action_type=options[i%3]
)
results = Foo.objects.values('action_type').annotate(Count('action_type'))
print results
生成一个包含以下内容的数组
{'action_type__count': 11, 'action_type': u'created'},
{'action_type__count': 11, 'action_type': u'deleted'},
{'action_type__count': 10, 'action_type': u'updated'}