问题
I've been searching for a while now for a solution to my problem, but I can't seem to figure this out.
So I have two models:
class Messages(models.Model):
_db = 'somedb'
id = models.IntegerField(primary_key=True)
text = models.TextField()
class MessageTags(models.Model):
_db = 'somedb'
id = models.IntegerField(primary_key=True)
text = models.TextField()
tag = models.ForeignKey(Tag)
message = models.ForeignKey(Messages, related_name='tags')
I am able to query the tags for a given message using the following call:
test = Messages.get(id=234124).tags.all()
^ returns a list of MessageTags
What I would like to do, is to in theory perform a left join, where I get all the messages for a certain criteria with the associated MessageTags objects. I was pointed in the direction of using select_related, but I cannot get anything to work.
How do I get the list of messages, with the MessageTags as an attribute of each as .tags (or anything else..)
Thank you!!
回答1:
I don't believe select_related
is going to be able to perform in the method you're looking for. But really, neither would a left join.
Think of it this way: One message could have 5 tags. If you do a join, you will get 5 rows in your result set for that one message, which makes it look like 5 messages.
Now, as you noted, you can reference .tags.all()
on an individual message and get all of the MessageTags associated with that Message. If I understand your case correctly, this is actually what you're looking for.
Of course, if you're trying to optimize the number of queries executed, I would recommend looking at prefetch_related
. Here is an example of how you could use this:
messages = Messages.objects.filter(text__icontains='foobar').prefetch_related('tags')
for message in messages:
for tag in message.tags.all():
print('Message id', message.id, '- tag', tag.text)
That should execute 2 queries:
- Retrieve your filtered listed of messages
- Retrieve all tags related to those messages
来源:https://stackoverflow.com/questions/33224827/using-select-related-to-get-related-name-objects