I would like to get the related objects of each object in a queryset.
Example:
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
class Synonym:
value = models.CharField(max_length=100)
class Name:
synonyms = GenericRelation(Synonym)
names = Name.objects.all()
synonyms = names.values_list('synonyms', flat=True) # <- returns the database id but not the object
But the value_list method returns only the id of the objects within the queryset.
I could flatten the output propably like this:
[synonym for name in list(names) for synonym in name.synonyms.all()]
But I wondered if there is a way to directly get the objects?
CodePudding user response:
What you already listed here is correct
qs = Name.objects.all()
[synonym for synonyms in list(qs) for synonym in synonyms]
But can be (Maybe) opitimized with (Need testing):
qs = Name.objects.all()
synonyms = []
for obj in qs:
synonyms.extend(obj.synonyms.all())
CodePudding user response:
You can specify a value for the related_query_name=…
parameter [Django-doc]:
from django.contrib.contenttypes.fields import GenericRelation
class Name(models.Model):
synonyms = GenericRelation(Synonym, related_query_name='name')
You can then fetch items in reverse, for example with:
Synonym.objects.filter(name__isnull=False).distinct()
will fetch all Synonym
s with a related Name
object, whereas for example:
Synonym.objects.filter(name__value__startswith='a').distinct()
will retrieve all Synonym
s for which there is a related Name
object where the value
starts with 'a'
.