Я занимаюсь разработкой системы рассылки новостей. В этой системе есть 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)
Теперь представьте, что я хочу разослать новостной бюллетень нескольким категориям новостных рассылок, при этом новостные рассылки не отправляются на один адрес электронной почты несколько раз. Это может произойти, если один NewsletterAbo находится в нескольких категориях Newsletter.
До сих пор я собираю 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 - это теперь список предметов без дубликатов.
У меня такой вопрос: есть ли более «django-ish» способ сделать это, используя ORM.
Любая помощь приветствуется.
UPDATE:
С помощью ответа lazerscience я нашел следующий код, который соответствует моим потребностям:
qs=NewsletterAbo.objects.filter(categories__is_active=True,
categories__id__in=[1,2,3,4],
is_active=True).distinct()
Эта строка кода возвращает все информационные бюллетени, которые мне нужны. Новый qs хранит этот список (если честно, это набор запросов) из тех предметов, которые я ранее хранил в abolist.
Спасибо:)!