ubiqum
ubiqum

Reputation: 115

Get rid of nested serialized data and make custom data format

I have Serializer data format like this, where task is ForeignKey to another model:

class OfferSerializer(serializers.ModelSerializer):
    class Meta:
        model = Offer
        fields = ("id", "task", "type")
        read_only_fields = ("id", "task", "type")
{
  "id": 1,
  "task": 1,
  "type": "offer"
},
{
  "id": 2,
  "task": 2,
  "type": "counter_offer"
}

Code from my views.py

...
offers_queryset = Offer.objects.all()
serializer = self.get_serializer(offers_queryset, many=True)
return Response(serializer.data)

I need to expand Task for some information and get rid of nesting. Right now I can only achieve this type:

class TasksOffersSerializer(serializers.ModelSerializer):
    task = TaskSerializer(read_only=True)

    class Meta:
        model = Offer
        fields = ("id", "task", "type")
        read_only_fields = ("id", "task", "type")
{
  "id": 1,
  "task": {
            "id": 1,
            "task_fields": "values"
          },
  "type": "offer"
},
{
  "id": 2,
  "task": {
            "id": 2,
            "task_fields": "values"
          },
  "type": "counter_offer"
},

My goal is to retrieve data in format like this, without nesting data:

[
  {
    "offer": {
               "id": 1,
               "type": "offer"
             }
    "task": {
              "id": 1,
              "task_fields": "values"
            }
  },
  {
    "offer": {
               "id": 2,
               "type": "counter_offer"
             }
    "task": {
              "id": 2,
              "task_fields": "values"
            }
  },
]

Is it possible to do with DjangoORM or should I manipulate querysets like lists and dictionaries with Python somehow?

Edit: My models (simplified)

class Task(models.Model):
    description = models.CharField(max_length=128)
    ...

class Offer(models.Model):
    task = models.ForeignKey("task.Task", on_delete=models.CASCADE)
    price = models.IntegerField()
    ...

The best I want to achieve is

class TasksOffersSerializer(serializers.Serializer):
    task = TaskSerializer()
    offer = OfferSerializer()

Upvotes: 0

Views: 78

Answers (2)

ubiqum
ubiqum

Reputation: 115

I ended up with this serializer

class TasksOffersSerializer(serializers.Serializer):
    task = TaskSerializer()
    offer = serializers.SerializerMethodField()

    def get_offer(self, obj: Offer):
        return OfferSerializer(obj).data

Upvotes: 0

SBN
SBN

Reputation: 123

You can use a custom serializer in django.In the views you can retrieve the response from the 'data' key.


class TasksOfferSerializer(serializers.Serializer):

    data = serializers.SerializerMethodField()

    def get_data(self, obj):
        return response = {
            "offer": {
                    "id": obj.id,
                    "type": obj.type
                }
            "task":{
                    "id":obj.task.id,
                    "task_name": obj.task.name
                }    
            }

Upvotes: 1

Related Questions