niklas
niklas

Reputation: 3011

django rest framework view with merged results from different object serializers

having the following models

class TreeLifephase(DBordered):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

class TreeWidth(DBordered):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

and many more like this, that contain editable attributes of my Tree objects. For a select field on the UI I want to have all available treelifephases and treewidths with one query - to have a json result that looks something like

{
    "treelifephases": [
        {
            "id": 1,
            "name": "young"
        },
        {
            "id": 2,
            "name": "medium"
        },
        {
            "id": 3,
            "name": "old"
        }
    ],
    "treewidths": [
        {
            "id": 1,
            "name": "10-20cm"
        },
        {
            "id": 2,
            "name": "21-30cm"
        },
        {
            "id": 3,
            "name": "31-40cm"
        }
    ]
}

I have serializers for the Models at hand and it would be awesome to have a view that could just get a list of serializers to return a resultset like the above.

Upvotes: 1

Views: 671

Answers (2)

niklas
niklas

Reputation: 3011

I came up with a good solution for my use case which I claryfied in the question above:

1st: I wrote a Serializer that only gives me the id and the name

class IDNameSerializer(serializers.BaseSerializer):
    def to_representation(self, obj):
        return {
            'id': obj.id,
            'name': obj.name
        }

2nd: I wrote a view that gives me the required json response with the help of the @api-view decorator from django-rest-framework

from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET'])
def tree_select(request):
    result = {}
    result['treelifephases'] = IDNameSerializer(TreeLifephase.objects.all(),many=True).data
    result['treewidths'] = IDNameSerializer(TreeWidth.objects.all(),many=True).data
    return Response(result)

Why I chose this as an answer:

  • Through use of @api_view decorator, we can still use permission classes and other sugar
  • It gives the json response in the required format
  • It is easy to alter when new fields might come there is only the view to be changed
  • I don't need a django model only for serialization
  • It is simple!

Upvotes: 0

levi
levi

Reputation: 22697

You can use SerializerMethodField and you need to create a model, in order to use model serializer.

class FullTree(serializers.ModelSerializer):
    full_tree =  serializers.SerializerMethodField()

    class Meta:
          model = FullTreeModel
          fields = ('treewidth','lifephase')



    get_full_tree(obj):
       treewidth = obj.treewidths # get all your treewidth
       lifephase = obj.lifephases# get all your lifephases
       //build your tree with your serializers
       return your_full_tree

Upvotes: 2

Related Questions