2

I am trying to do GET with a request parameter in Django Rest.

views.py :-

class ItemView(generics.ListCreateAPIView):

    queryset = itemlist.objects.all()
    serializer_class = ItemListSerializer

    def perform_create(self, serializer):

        serializer.save()

    def get_queryset(self):

        queryset = itemlist.objects.all()

        get_param = self.request.GET.get('get_param')
        if get_param:
            queryset = queryset.filter(item_name=get_param)

        return queryset

urls.py :-

urlpatterns = {

    url(r'^itemlists/$', ItemView.as_view(), name="itemlist")
}

itemlists/ returns the list of all items. But, I want to return for a particular item, where let's say, item_name = "abcd" URL will look like, itemlists/abcd/

I tried with,

urlpatterns = {

    url(r'^itemlists/(?P<pk>\d+)$', ItemView.as_view(), name="itemlist")
}
1
  • Can you please search for DetailView. I hope that will serve your purpose. Commented Dec 17, 2017 at 8:54

1 Answer 1

2

If you'd like to keep it plain and simple, django rest framework provides this functionality right out of the Box (ish). In order to get it working, you'll need to edit your code a little bit.

Django rest framework provides so called viewsets, which provide CRUD operation endpoints right out of the box. What's more, by subclassing rest_framework.generics.GenericViewSet and selectively adding so called mixins, we can limit the operations we want to provide for this endpoint.

In order to achieve your desired functionality, we will

  • Implement a custom viewset, which provides list, create and retrieve functionality
  • Implement a SimpleRouter which takes care of the routing for us and include it in our root url conf.

In your view.py

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (RetrieveModelMixin, CreateModelMixin, ListModelMixin, RetrieveModelMixin)

class ItemViewSet(RetrieveModelMixin, CreateModelMixin, ListModelMixin, GenericViewSet):

    queryset = itemlist.objects.all()
    serializer_class = ItemListSerializer
    lookup_field = 'item_name'

What's going on here? While GenericViewSet gives us a startingpoint, django rest framework's mixins enables us to selectively throw in actions we want to implement, i.e. retrieve ("detail view"), list and so on. For more info, check this link. By throwing in RetrieveModelMixin, CreateModelMixin and ListModelMixin, we have created a viewset with your desired functionality. Awesome right?

Out of the box, the RetrieveModelMixin dealing with instance-level lookups performs the query based on the pk attribute. In order to change it, we override the lookup_field attribute to 'item_name'. Once we've done this, your custom viewset is ready to go. Next, we'll use django rest framework's SimpleRouter to automagically include all our viewset's routes for us.

In your urls.py

Simply pass your view to a Router during instantiation and include it in your url conf. Note that urlconf is a list and has brackets, not curly braces (as in your question).

from rest_framework import routers
from somwhere.views import ItemViewSet
# ...
router = router.SimpleRouter()
router.register(r'itemlist', ItemViewSet)

urlpatterns = [
    # ... other stuff
    url(r'', include(router.urls)),
]

Limitations

The CreateModelMixin does not create a new model instance, but delegates this task to the serializer set in serializer_class. That is, to get the above code to work, you either need to use a ModelSerializer, what judging from the name ItemSerializer you're already doing or implement your custom creation logic. This can either happen in your custom viewset by overriding the create method in your ItemViewSet class or by implementing create on your serializer.

Cheers, D

Sign up to request clarification or add additional context in comments.

7 Comments

Hi, Thanks for answering. What should be my URL here ?
I mean, the GET call url
If urls.py is your root conf, your list endpoint is {host}/itemlist/, your Detail view is {Host}/itemlist/{item_name}/
It is not resulting the view of that particular {item_name} , instead it is showing all the items, that is itemlist/
Can you paste your code in your question? I tried the code before submitting my answer and it works for me.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.