查询数据库后在Python模型对象中进行过滤和分组

时间:2018-09-01 12:04:29

标签: django django-models django-queryset

我有以下模型:

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

1 个答案:

答案 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