Getting random object of a model with django-rest-framework
django, django-rest-framework, random
Solution
As @CarltonGibson noticed, `queryset` is an attribute of `RandomObject` class. Hence it cached and cannot be changed any later. So if you want to make some changeable queryset (like getting random objects at every request) in some `APIView`, you must override a `get_queryset()` method. So instead of
class RandomObject(generics.ListAPIView):
queryset = MyModel.objects.all().filter(id = pick_random_object())
...
you should write something like this:
class RandomObject(generics.ListAPIView):
#queryset = MyModel.objects.all().filter(id = pick_random_object())
def get_queryset(self):
return MyModel.objects.all().filter(id = pick_random_object())
Here `pick_random_object()` is a method to get random `id` from the model.
Problem
In my Django project I need to provide a view to get random object from a model using django-rest-framework. I had this ListAPIView: ``` class RandomObject(generics.ListAPIView): queryset = MyModel.objects.all().order_by('?')[:1] serializer_class = MyModelSerializer ... ``` It worked fine but `order_by('?')` takes a lot of time when launched on big database. So I decided to use usual Python random. ``` import random def pick_random_object(): return random.randrange(1, MyModel.objects.all().count() + 1) class RandomObject(generics.ListAPIView): queryset = MyModel.objects.all().filter(id = pick_random_object()) ... ``` I found out a strange thing when tried to use this. I launched Django development server and sent some GET requests, but I got absolutely the same object for all of the requests. When dev server restarted and another set of requests sent I'm getting another object, but still absolutely the same one for all of requests - even if `random.seed()` was used first of all. Meanwhile, when I tried to get a random object not via REST but via `python manage.py shell` I got random objects for every time I called `pick_random_object()`. So everything looks good when using shell and the behavior is strange when using REST, and I have no clue of what's wrong. Everything was executed on Django development server (`python manage.py runserver`).