Search code examples
pythondjangodjango-viewsdjango-querysetdjango-testing

Django REST TestCase: How to retrieve a response queryset that wasn't assigned to an attribute?


For a view that extends a generic ListAPIView and returns a queryset by simply assigning a collection to the View queryset attribute, like so:

class MyView(ListAPIView):
   queryset = MyModel.objects.all()

How can the queryset be retrieved in the TestCase for this view?

def test_my_view(self):
    request = self.factory.get('my/url') # self.factory was set in the setUp method
    response = MyView.as_view()(request)
    self.assertEqual(response.status_code, 200)
    # I'd like to now test the query set, something like
    # self.assertQuerysetEqual(response.queryset, [])

I've found that on querysets that are assigned to an attribute, the way to retrieve the queryset is this:

response.context['queryset_attribute_name']

But I'd like my view to act like a simple REST endpoint for the front end and not add the attribute name to it.

This seems like such a simple thing to do, but I'm new to Django and just can't figure out how to do it and already wasted way too much time searching for it...


Solution

  • Instead of trying to capture the actual QuerySet that was used for the response and write a test for it, you should look at the response itself. Since you're writing an API I assume you want to assert that the JSON contains the correct data.

    For the django-rest-framework, a Response object has two attributes: response.data is the python serialised data used to render the JSON, while response.content is the JSON itself.

    So, if your MyModel doesn't have any objects yet, you could test:

    self.assertEqual(0, len(response.data))
    

    or

    self.assertEqual("[]", response.content)