Reputation: 4466
I'm strugling with a complex query that I cannot translate into the django orm.
I'm sending messages. Each message can be sent to recipients and / or groups of recipients. I need to get a list of all the recipients for a given message, and I don't want any duplicates in my list (same user can be in different groups).
Here are my models so far:
class Contact(models.Model):
email = models.EmailField(_('Email'), null=True, blank=True)
groups = models.ManyToManyField('Group', related_name='members', null=True,
blank=True, verbose_name=_('Groups'))
class Group(models.Model):
name = models.CharField(_('Name'), max_length=50)
class Message(models.Model):
body = models.TextField(_('Body'))
recipients = models.ManyToManyField('contacts.Contact',
null=True, blank=True,
related_name='messages',
verbose_name=_('Recipients'))
groups = models.ManyToManyField('contacts.Group',
null=True, blank=True,
related_name='messages',
verbose_name=_('Groups'))
Can you think of a clever way to do this?
Thanks.
Upvotes: 3
Views: 129
Reputation: 309119
Use Q objects so that you can select both contacts messaged as part of a group and contacts that were individual recipients in the same queryset.
Then use distinct()
so that you don't get duplicates.
If you're not familiar with the double underscore notation (e.g. groups__messages
), then see the docs on following relationships "backward".
Putting it all together, you have:
message = message.objects.get(id=message_id)
Contact.objects.filter(Q(groups__messages=message)|Q(messages=message)).distinct()
You may want to encapsulate the above query in a method on the Message model:
class Message(models.Model):
# field definitions
def get_recipients(self):
return Contact.objects.filter(Q(groups__messages=message)|Q(messages=message)).distinct()
Then in your view, you can simply write message.get_recipients()
.
Upvotes: 3