【问题标题】:Retrieve multilple objects from multiple categories (many-to-many rel) more djangoish way从多个类别(多对多 rel)中检索多个对象更 djangoish 方式
【发布时间】:2012-02-10 18:01:14
【问题描述】:

我正在开发一个通讯系统。在这个系统中,有 Newslettercategories 和 Newsletterabos(发言订阅),它们具有多对多的关系。 考虑这两个模型:

class NewsletterCategory(models.Model):
    title = models.CharField(max_length=255, unique=True)
    slug = models.SlugField(max_length=255, unique=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering=['title']

    def __unicode__(self):
        return self.title


class NewsletterAbo(models.Model):
    abo_id = models.CharField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255, unique=False)
    last_name = models.CharField(max_length=255, unique=False)
    email = models.EmailField(max_length=75, unique=False)
    is_active = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    categories = models.ManyToManyField(NewsletterCategory, blank=True)

    class Meta:
        ordering=['last_name']

    def __unicode__(self):
        return (self.last_name + ', ' +self.first_name)

现在想象一下,我想向多个 NewsletterCategories 发送时事通讯,而不会将时事通讯多次发送到一个电子邮件地址。如果一个 NewsletterAbo 位于多个 NewsletterCategories 中,则可能会发生这种情况。 到目前为止,我收集了我想要发送邮件的 Abos,与此类似(避免重复):

# get all NewsletterCategories that are active, 
categories = NewsletterCategory.objects.filter(is_active=True)
# initialize empty list for storing NewsletterAbos
abolist = []
# loop through retrieved NewsLetterCategories
for cat in categories:
    # get NewsletterAbos that are related to a NewsletterCategory
    abos = cat.newsletterabo_set.filter(is_active=True)
    # add retrieved NewsletterAbos to list
    abolist += abos
# removing duplicate entries
abolist = set(abolist)

# ... do something else then like sending out newsletter to abolist subscriptions

Abolist 现在是一个没有重复项的 abolist 项目列表。 我的问题是:使用 ORM 是否有更“django-ish”的方式来做到这一点。

感谢任何帮助。

更新: 在 lazerscience 答案的帮助下,我找到了适合我需要的以下代码:

qs=NewsletterAbo.objects.filter(categories__is_active=True, 
                                categories__id__in=[1,2,3,4], 
                                is_active=True).distinct()

这行代码检索我需要的所有 NewsletterAbos。新的 qs 存储了我以前存储在 abolist 中的 abo 项目列表(老实说,它是一个查询集)。

谢谢:)!

【问题讨论】:

    标签: django orm django-orm


    【解决方案1】:

    如果您只需要发送时事通讯的电子邮件地址,您可以这样做:

    qs = NewsletterAbo.objects.filter(categories_set__is_active=True)
    qs = qs.values_list('email', flat=True).distinct()
    

    这将为您提供唯一电子邮件地址的平面列表,同时仅访问数据库一次。 查看 django 文档以获取有关 distinct()values()/values_list() 的更多信息。

    【讨论】:

      猜你喜欢
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多