Reputation:
so I have this model:
class Message(models.Model):
creator = models.ForeignKey(User, unique=True)
note = models.CharField(max_length=200, blank=True)
recipients = models.ManyToManyField(User, related_name="shared_to")
read = models.ManyToManyField(User, related_name="read", blank=True)
I want to filter on people who are in both recipients and read, currently I'm doing this.
messages = user.shared_to.all()
for message in messages:
if user not in message.read:
do something
I'm sure there is a way to filter this but I can't figure out how.
Upvotes: 1
Views: 3575
Reputation: 43912
If you use the Django development version, or wait until version 1.1 is released, then your filters can reference other fields in the model. So, your query would look like this:
>>> Message.objects.filter(recipients=F('read'))
(Note: I spelled reciepients the same as you had in your model, although the correct spelling would be "recipients")
Edit:
Ok, your question is confusing. When I gave the above answer I was reading your statement that you wanted all users who were in both "recipients" and "read"). But then reading your code snippet it looks like you want a list of users who are recipients, but not yet in the "read" list.
This is probably what you want, but I'm not completely sure because of the vague requirements and I can't quickly test it:
# Get list of recipients
shared_to = Message.shared_to.all().values('id')
# Now list of recipients who are not in the read field
unread = Message.objects.exclude(recipients__in=shared_to)
This will make a single query, but if you are using MySQL it could still be more efficient to do two queries (read the Performance considerations warning).
Upvotes: 1
Reputation: 363
I think that I originally misread your question. Try the following query.
for message in user.shared_to.exclude(read__id__in=[user.id]):
do_something()
Upvotes: 0