I need to get at query string values in some viewset logic (in this case, derived from ModelViewSet). Everything I've read, including the Django REST Framework doc, says that request is an attribute of the viewset. But when I actually try to refer to it in code, no matter how I do so, I am shown the runtime error 'AddressViewSet' object has no attribute 'request' . Here's one simplified version of the class definition that triggers the error:
class AddressViewSet(viewsets.ModelViewSet):
def __init__(self, suffix, basename, detail):
attendee = ""
if self.request.query_params.get('attendee'):
attendee = self.request.query_params.get('attendee')
self.serializer_class = AddressSerializer
self.queryset = Address.objects.all()
How does one read request properties in viewset logic in DRF?
CodePudding user response:
You are overriding the incorrect method. The ViewSet like all class based views in Django (All DRF views inherit from django.views.generic.View
down the line) is instantiated (The pattern usually seen as View.as_view()
internally creates an instance of the class) before the request is even received. This instance is used in the url patterns and when a request matching the url pattern is found a dynamically created function is called for the view which then calls dispatch
.
Coming back to the point __init__
is not the correct method to override, if you want to filter the queryset you should instead be overriding get_queryset
:
class AddressViewSet(viewsets.ModelViewSet):
queryset = Address.objects.all()
serializer_class = AddressSerializer
def get_queryset(self):
queryset = super().get_queryset()
attendee = ""
if self.request.query_params.get('attendee'):
attendee = self.request.query_params.get('attendee')
# Filter queryset here
return queryset
CodePudding user response:
What I did not understand is that you can override a function get_queryset() but if you do that you do not assign queryset directly - that happens automatically. Once that overridden function is called the request is available as a property of the viewset, so it can be referred to there.