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.
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)
class ContainerViewSet(viewsets.ModelViewSet): queryset = Container.objects.all() # only a handful of containers serializer_class = ContainerSerializer
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')
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With