我正在开发一个时事通讯系统。在这个系统中有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项目。
谢谢:)!
答案 0 :(得分:1)
如果您只需要发送简报的电子邮件,您可以这样做:
qs = NewsletterAbo.objects.filter(categories_set__is_active=True)
qs = qs.values_list('email', flat=True).distinct()
这将为您提供一个唯一的电子邮件地址列表,同时只访问数据库一次。
有关distinct()
和values()
/ values_list()
的更多信息,请查看django文档。