代码之家  ›  专栏  ›  技术社区  ›  user3541631

查询数据库后Python模型对象的过滤和分组

  •  2
  • user3541631  · 技术社区  · 6 年前

    我有以下型号:

    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

    伪代码/逻辑:

      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 回复  |  直到 6 年前
        1
  •  2
  •   willeM_ Van Onsem    6 年前

    itertools.groupby 将一个iterable分组为一个由两个元组组成的iterable。然而,为了有效地处理这个问题,对(相关的)数据进行预取是很重要的 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元组的列表:每个元组的第一个元素包含相关的 对象,元组的第二项 Item 对象(带 email=False ). 用户 没有这样的问题 s遗嘱

    因此,如果您想发送电子邮件,可以循环查看2元组列表,如:

    for user, items in result:
        user_context { 
            'subject' : 'some subject'
        }
        user_context['content] = items
        send_email(user_context)

    只有 对…感兴趣 那里有一个 电子邮件=错误 ,则只需查询:

    User.objects.filter(item__email=False)