Issue
I have 2 django models linked like this:
class ModelA(models.Model):
id = models.UUIDField(primary_key=True)
# some other fields here
class ModelB(models.Model):
modela_id = models.UUIDField(primary_key=True)
unique_field = models.FloatField()
order = models.IntegerField(primary_key=True)
random_field = models.FloatField()
and serializers for these 2 models:
class ModelASerializer(serializers.Serializer):
id = serializers.CharField(help_text="Measurement ID")
# some other fields here
b_objects = ModelBSerializer(many=True)
classModelBSerializer(serializers.Serializer):
id = serializers.CharField(source="order")
random_field = serializers.FloatField()
unique_field = serializers.FloatField()
I want to write an endpoint that will return the list of ModelA entities and all the related ModelB objects to the particular ModelA object.
I have this currently, it works just fine:
ModelA.objects.prefetch_related("b_objects").all()
which returns a list of objects like this one:
{
"id": "92eb8314-3f26-4bf6-8cc0-83d2935434d9",
### modelA fields here
"b_objects": [
{
"id": "1",
"random_field": 1.0,
"unique_field": 0.1
},
{
"id": "2",
"random_field": 5.0,
"unique_field": 0.1
}
]
}
What I want here is to move "unique_field" from inner level to the level of modelA so that it would return:
{
"id": "92eb8314-3f26-4bf6-8cc0-83d2935434d9",
"unique_field": 0.1
### modelA fields here
"b_objects": [
{
"id": "1",
"random_field": 1.0
},
{
"id": "2",
"random_field": 5.0
}
]
}
It's 100% that all values of unique_field will be equal in all the b_objects within particular modelA objects.
I tried to add .annotate(unique_value="b_objects") and other inside of annotate, but it raises an error:
QuerySet.annotate() received non-expression(s): b_objects.
Is there any way of achieving this using queryset API?
Solution
Try adding unique_field = serializers.FloatField()
to ModelASerializer
. You have to add
def to_representation(self, instance):
data = super().to_representation(instance)
unique_field_values = [b_obj['unique_field'] for b_obj in data['b_objects']]
if unique_field_values:
data['unique_field'] = unique_field_values[0]
for b_obj in data['b_objects']:
b_obj.pop('unique_field', None)
return data
and that will take the unique_field
from ModelB
and add it into outer returning object.
Answered By - zarnocha
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.