我有以下模型:
class Item(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='item',on_delete=models.SET_NULL)
email = models.BooleanField(blank=True, null=True)
.....
我需要向user
发送电子邮件,其中Item
email
属性为False
。
我有以下查询:
items = Item.objects.filter(email=False)
我想按用户过滤/分组项目。我想用python做,因为我想延迟发送电子邮件,而不是一次查询太多就使数据库不堪重负。
对于每次使用,我都想创建一个context
字典,然后将其发送到Django电子邮件。
伪代码/逻辑:
user_context {
'subject' : 'some subject'}
for item in items:
if user is the same:
user_context['content] = append item
if finished same_user items:
send_email(user_context)
context = {} # reset context
答案 0 :(得分:2)
您可以使用itertools.groupby
将可迭代项分组为2个元组的可迭代项。为了有效地处理此问题,重要的是对(相关)User
对象进行一些预取,例如:
from operator import itemgetter
from itertools import groupby
qs = Item.objects.filter(email=False).order_by('user_id').prefetch_related('user')
result = [
(k, list(vs))
for k, v in groupby(qs, key=attrgetter('user'))
]
现在result
是一个2元组的列表:每个元组的第一个元素都包含相关的User
对象,而元组的第二个元素则是相关Item
对象的列表( email=False
)。没有此类User
的{{1}}个将不出现在列表中。
因此,如果您要发送电子邮件,可以遍历2个元组的列表,例如:
Item
如果您只是在与for user, items in result:
user_context {
'subject' : 'some subject'
}
user_context['content] = items
send_email(user_context)
存在User
的{{1}}的{{1}}中被 感兴趣,那么您只需要查询:
Item