If for an example I have 2 models and a simple View:
class Recipe(model.Model):
created_at = model.DateField(auto_add_now=True)
class RecipeBook(model.Model):
recipes = model.ManyToManyField(Recipe)
...
class RecipeBookList(ListAPIView):
queryset = RecipeBook.objects.all()
serializer_class = RecipeBookSerializer
...
class RecipeBookSerializer(serializers.ModelSerializer):
recipe = RecipeSerializer(many=True, read_ony=True)
class Meta:
model = RecipeBook
fields = "__all__"
What would be the best way, when showing all Restaurants with a simple GET
method, to show only the first 5 recipes created and not all of them?
QuerySet way:
You can specify custom Prefetch
operation in your queryset to limit the prefetched related objects:
queryset.prefetch_related(Prefetch('recipes', queryset=Recipe.objects.all()[:5]))
Docs: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-objects
Serializer way:
You can use source
to provide a custom method to return a custom queryset
class RecipeBookSerializer(serializers.ModelSerializer):
recipes = RecipeSerializer(many=True, read_only=Treue, source='get_recipes')
class Meta:
model = RecipeBook
fields = "__all__"
def get_recipes(self, obj):
return obj.recipes.all()[:5]
Then use prefetch_related("recipes")
to minimize related queries.
Source: django REST framework - limited queryset for nested ModelSerializer?
The problem with the serializer way is that either a related query for recipes is performed per recipe book object or all related recipes are pre-fetched from the beginning.