Getting Multiple Objects using Django rest_framework RetrieveAPIView

Question:

Currently I have this class inside my shop’s view.py

class ShopDetailAPIView(RetrieveAPIView):

    queryset = Shop.objects.all()
    serializer_class = ShopDetailSerializer
    lookup_field = 'Suburb'
    permission_classes = [IsAuthenticated]

And my shop’s urls.py which displays this specific api:

urlpatterns = [

    url(r'^$', ShopListAPIView.as_view(), name = 'list' ),
    url(r'^(?P<Suburb>w+)/$', ShopDetailAPIView.as_view(), name = 'detail'),
]

The aim of the ShopDetailAPIView class is to display a filtered version of the data stored inside the database. So that if a user enters

 http://example.com/shop/locationname

The link will display Django Rest Framework API according to the location.

The problem I am facing is that when there are more than one objects, the page returns:

get() returned more than one Shop -- it returned 3!

I think my solution is to change my queryset to

queryset = Shop.Objects.filter(Suburb = suburb)

However I have no idea how to implement this using RetrieveAPIView.

I know there are alternatives such as django-filter which would work perfectly in this situation. However is there any way to implement my code above to show more than 3 objects?

Thank you

Asked By: Phurich.P

||

Answers:

You can’t use RetrieveAPIView for several instances.
However, you likely want some filtering. I’d recommend using url arguments for that along with the ListAPIView:

http://www.django-rest-framework.org/api-guide/filtering/#filtering-against-the-url

Answered By: Linovia

From the docs of RetrieveAPIView

Used for read-only endpoints to represent a single model instance.

RetrieveAPIView is used to serialize and return exactly one object, which is returned by either get_object(self) method or by a lookup on queryset.

If you want to display/return multiple filtered objects, you can use ListAPIView. Your filtering can be done in the get_queryset(self) method, something as following

def get_queryset(self):
    return Shop.Objects.filter(Suburb = self.suburb)

Or better, use drf’s built-in Filtering.

Answered By: Ravi Teja