Search code examples
sqldjangodjango-modelsdjango-select-relateddjango-related-manager

How to Annotate Specific Related Field Value


I am attempting to optimize some code. I have model with many related models, and I want to annotate and filter by the value of a field of a specific type of these related models, as they are designed to be generic. I can find all instances of the type of related model I want, or all of the models related to the parent, but not the related model of the specific type related to the parent. Can anyone advise?

I initially tried

parents = parent.objects.all()
parents.annotate(field_value=Subquery(related_model.objects.get(
                                     field__type='specific',
                                     parent_id=OuterRef('id'),
                                    ).value)))

But get the error This queryset contains a reference to an outer query and may only be used in a subquery. When I tried

parents = parent.objects.all()
parents.annotate(field_value=Q(related_model.objects.get(
                              field__type='specific',
                              parent_id=F('id'),
                             ).value)))

I get DoesNotExist: related_field matching query does not exist. which seems closer but still does not work.

Model structure:

class parent(models.Model):
    id = models.IntegerField(null=False, primary_key=True)

class field(models.Model):
    id = models.IntegerField(null=False, primary_key=True)
    type = models.CharField(max_length=60)

class related_model(models.Model):
    parent = models.ForeignKey(parent, on_delete=models.CASCADE, related_name='related_models')
    field = models.ForeignKey(field, on_delete=models.CASCADE, related_name='fields')

Is what I want to do even possible?


Solution

  • Never mind I decided to do a reverse lookup, kinda like

    parent_ids = related_model.objects.filter(field__type='specific', parent_id__in=list_of_parents).values_list('parent_id')
    
    parents.objects.filter(id__in=parents_id)