Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django REST framework - limited queryset for nested ModelSerializer?

I have a ModelSerializer, but by default it serializes all the objects in my model. I would like to limit this queryset to only the most recent 500 (as opposed to all 50 million). How do I do this?

What I have currently is the following:

class MyModelSerializer(serializers.ModelSerializer):     class Meta:         model = MyModel 

The reason I don't think I can just specify the queryset in my viewset is that this is in fact the nested portion of another serializer.

models.py

class Container(models.Model):     size  = models.CharField(max_length=20)     shape = models.CharField(max_length=20)  class Item(models.Model):     container = models.ForeignKey(Container, related_name='items')     name  = models.CharField(max_length=20)     color = models.CharField(max_length=20) 

views.py

class ContainerViewSet(viewsets.ModelViewSet):     queryset = Container.objects.all()  # only a handful of containers     serializer_class = ContainerSerializer 

serializers.py

class ItemSerializer(serializers.ModelSerializer):     class Meta:         model = Item         fields = ('name', 'color')  class ContainerSerializer(serializers.ModelSerializer):     items = ItemSerializer(many=True)  # millions of items per container     class Meta:         model = Container         fields = ('size', 'shape', 'items') 
like image 721
tadasajon Avatar asked Aug 14 '14 16:08

tadasajon


People also ask

How do you pass extra context data to Serializers in Django REST framework?

In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.

How do I pass Queryset to serializer?

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

What is Queryset in Django REST framework?

The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects. The default behavior of REST framework's generic list views is to return the entire queryset for a model manager.


1 Answers

In your View Set you may specify the queryset like follows:

from rest_framework import serializers, viewsets  class MyModelSerializer(serializers.ModelSerializer):     class Meta:         model = MyModel  class MyModelViewSet(viewsets.ModelViewSet):     queryset = MyModel.objects.all()[:500]     serializer_class = MyModelSerializer 

I think what you are looking for is the SerializerMethodField.

So your code would look as follows:

class ContainerSerializer(serializers.ModelSerializer):     items = SerializerMethodField('get_items')      class Meta:         model = Container         fields = ('size', 'shape', 'items')      def get_items(self, container):         items = Item.objects.filter(container=container)[:500]  # Whatever your query may be         serializer = ItemSerializer(instance=items, many=True)         return serializer.data 

The one catch is that the SerializerMethodField is read only.

like image 115
Johndt Avatar answered Oct 06 '22 15:10

Johndt