如何在Django REST fram中支持端点的所有REST操作

2024-05-15 22:29:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个订阅模型,如下所示

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)

我想创建一个端点,它允许POST, PATCH, DELETE, GET

所以我做了以下事情

视图.py

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

序列化程序.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?

网址.py

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

问题

  1. 当我发送一个PATCH请求时,使用上面的方法会得到一个错误。我该怎么解决?

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. 在发送修补程序请求时,我还想发送一个不在订阅模型上的“电子邮件”字段。这有可能吗?我需要POST (create)操作中的email字段,以便知道订阅属于哪个用户。

Tags: namepy模型viewmodelsupdatelengthmax
3条回答

为了创建一个对象,您必须实现官方文档中描述的create函数,可以找到here。对于修补,可以使用视图类中的部分参数:

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

对于订阅的删除,可以在视图类中执行delete调用时执行:

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

完整示例请参见this教程

此外,我认为应该在SubscriptionSerialiser元类中包含“id”字段,否则将很难进行更新/删除。我希望这有点帮助。

干杯, 托比

  1. 如果要使用允许执行这些操作的方法,则必须使用@detail_route(),其中还可以说明将使用哪些方法,如文档中所述:

    @detail_route(方法=['post']) def set_password(self,request,pk=无): user=self.get_object() serializer=PasswordSerializer(data=request.data) ...

所以为了能够使用它们,您应该添加下一个decorator

@detail_route(methods=['post', 'patch'])

  1. 要添加其他参数,可以对.save()参数执行此操作。您只需指明该邮件的名称,它们就可以覆盖.save()模型,以检查该邮件是否属于尝试订阅的用户。在这里,我把Django Rest文档所说的粘贴给您:

“将其他属性传递给.save()

。。。

可以通过在调用.save()时包含其他关键字参数来实现。例如:

serializer.save(owner=request.user)

这里我给你留下了更多信息的链接:

http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

最简单的方法就是这样做。

保持模型类不变

视图.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 

序列化程序.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

网址.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)),

)

相关问题 更多 >