Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to support all REST operations for an endpoint in django rest framework

I have a subscription model that looks like this

class Subscription(models.Model):
    name = models.CharField(max_length=100)
    quantity = models.IntegerField(max_length=20)
    stripe_id = models.CharField(max_length=100)
    user = models.ForeignKey(User)

I would like to create an endpoint that allows POST, PATCH, DELETE, GET

So I did the following things

views.py

class SubscriptionDetail(viewsets.ModelViewSet):
    serializer_class = SubscriptionSerializer
    permission_classes = (IsAuthenticated,)
    queryset = Subscription.objects.all()

serializers.py

class SubscriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subscription
        fields = ('name','quantity', 'stripe_id')

    def update(self, instance, validated_data):
        print "In update"

    #how do I write create and delete?

urls.py

 subscription = SubscriptionDetail.as_view({
     'patch': 'update'
 })
url(r'^rest-auth/subscription/$', subscription, name='something'),

Questions

  1. Using the above when I send a PATCH request, I get an error. How can I fix this?

Expected view SubscriptionDetail to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field attribute on the view correctly.

  1. While sending the patch request I would also like to send an 'email' field which is not on the subscription model. Is this possible to do? I need the email field in the POST (create) operation so that I know which user the subscription belongs to.
like image 608
Anthony Avatar asked Mar 21 '15 03:03

Anthony


People also ask

Does Django support REST?

Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs. Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django.

What is the correct command to run the Django REST server?

Let's make sure the app is up and running by using the Django runserver command. (drf) $ python3 manage.py runserver Django version 3.1. 5, using settings 'my_awesome_django_project. settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.

Can I use Django and Django REST Framework together?

Django Rest Framework makes it easy to use your Django Server as an REST API. REST stands for "representational state transfer" and API stands for application programming interface. Note that with DRF you easily have list and create views as well as authentication.


2 Answers

The easiest way is to do it this way.

keep the models class the same

views.py

from rest_framework import viewsets
#impost serializer and model class for subscription

class SubscriptionViewSet(viewsets.ModelViewSet):

    serializer_class = SubscriptionSerializer

    def get_queryset(self):
        queryset = Subscription.objects.all()
        #if you need to get subscription by name
        name = self.request.QUERY_PARAMS.get('name', None)
        if name is not None:
            queryset = queryset.filter(name=name)

        return queryset 

serializers.py

 class SubscriptionSerializer(serializers.ModelSerializer):
     class Meta:
         model = Subscription
         fields = ('name','quantity', 'stripe_id')

 # django will handle get, delete,patch, update for you ....
 # for customization you can use def update or def create ... to do whatever you need
 # def create(self, validated_data):
 # you can handle the email here
 # and something like subscription=        Subscription (name=validated_data['name'],vendor=validated_data['quantity']...)
 # subscription.save()
 # it will save whatever you want

urls.py

#use the router to handle everything for you
from django.conf.urls import patterns, include, url
from rest_framework import routers
#import your classes 


router = routers.DefaultRouter()
router.register(r'subscription', views.SubscriptionViewSet,base_name='subscription')

urlpatterns = patterns('',
url(r'^', include(router.urls)),

)
like image 83
ETS Avatar answered Sep 21 '22 18:09

ETS


For the creation of an Object you must implement the create function as described in the official documentation, found here. For patching you could use the partial argument from within you view class:

SubscriptionSerializer(subscription, data={'something': u'another', partial=True)

For deletion of the a Subscription, that could be done when you get the delete call as so in your view class:

if request.METHOD == 'DELETE':
       subscription = Subscription.objects.get(pk=pk)
       subscription.delete()

See this tutorial for complete example

Further more I think that you should include the "id" field in the SubscriptionSerialiser Meta class, otherwise it will be difficult to do the updates/deletions. I hope this helped a little.

Cheers, Tobbe

like image 45
Tobias Alm Avatar answered Sep 19 '22 18:09

Tobias Alm