【问题标题】:PUT and Delete Request in Django rest frameworkDjango rest 框架中的 PUT 和 Delete 请求
【发布时间】:2019-07-14 09:46:35
【问题描述】:

我是 Django 新手,我想知道如何在我的 Django REST API 项目中编写 PUT 请求和 Delete 方法。

我尝试过很多教程,但没有一个适用于我的代码。

我试过的代码是这样的

def put(self, request, pk):
        snippet = self.get_object(pk)
        serializer = UserSerializers(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
    snippet = self.get_object(pk)
    snippet.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

但不允许获取消息方法

以下是我的Models.py

from django.db import models


class Users(models.Model):
    user_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)
    profile_name = models.CharField(max_length=30)
    profile_picture = models.CharField(max_length=1000)
    phone = models.CharField(max_length=15)
    email = models.EmailField()
    password = models.CharField(max_length=25, default='')

    def __str__(self):
        return self.name

以下是我的serializers.py

from rest_framework import serializers
from .models import Users
from .models import UserPost


class UserSerializers(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'


class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'


class UserPostSerializers(serializers.ModelSerializer):
    class Meta:
        model = UserPost
        fields = '__all__'

以下代码包含我的 Views.py

from django.http import Http404
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from .models import Users
from .models import UserPost
from .serializers import UserSerializers, UserPostSerializers


class UsersList(APIView):

    def get(self, request):
        User_details = Users.objects.all()
        serializer = UserSerializers(User_details, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = UserSerializers(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserDetail(APIView):
    def get_object(self, pk):
        try:
            return Users.objects.get(pk=pk)
        except Users.DoesNotExist:
            raise Http404

    def get(self, request, pk):
        snippet = self.get_object(pk)
        serializer = UserSerializers(snippet)
        return Response(serializer.data)

    class UserViewSet(viewsets.ModelViewSet):
        queryset = Users.objects.all()
        serializer_class = UserSerializer

        @action(methods=['put'], detail=False)
        def filter_by_something(self, request):
            something = request.data.get('that_something')
            queryset = Users.objects.filter(something__exact=something)
            return Response(self.get_serializer(queryset, many=True).data)

以下代码包含urls.py

from sys import path

from django.urls import include
from rest_framework.urlpatterns import format_suffix_patterns
from app import views
from django.conf.urls import url
from django.contrib import admin

from rest_framework import routers
router = routers.DefaultRouter()



router.register('user_details', UserDetailViewSet)
urlpatterns = [path('api/', include(router.urls)), ...]
urlpatterns = [

    url(r'^admin/', admin.site.urls),
    url(r'^User_details/', views.UsersList.as_view()),
    url(r'^User_details/(?P<pk>[0-9]+)/', views.UserDetail.as_view()),
    url(r'^userpost_details/', views.UsersPostList.as_view()),

]
urlpatterns = format_suffix_patterns(urlpatterns)

【问题讨论】:

  • 您将 PUT/DELETE 添加到哪个视图?您对哪个 url 执行了 PUT/DELETE 操作?
  • @Linovia Views.py 在app文件夹中,url为127.0.0.1:8000/User_details
  • 您的 PUT/DELETE 可能适用于特定资源,而不是资源列表,这就是您得到错误的原因

标签: python django api django-rest-framework django-views


【解决方案1】:

UsersDetail 类中定义putdelete 方法。

class UsersDetail(APIView):
 def put(self, request, pk):
   // code

 def delete(self, request, pk):
   //code

如果以上不行也加http_method_names

class UsersDetail(APIView):
 http_method_names = ['GET', 'PUT', 'DELETE']

APIView 类继承自 Django 基础文件中定义的View 类。 dispatch 方法将检查 http_method_names 的有效方法。 PUTDELETE 与其他方法一起被列为有效方法。

参考:django/views/generic/base.py

  class View(object):
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
            extra={
                'status_code': 405,
                'request': request
            }
        )
        return http.HttpResponseNotAllowed(self._allowed_methods())

【讨论】:

    【解决方案2】:

    在 urls.py 中,您应该声明一个将您的 ViewSets 映射到 DRF 的路由器对象:

    from rest_framework import routers
    router = routers.DefaultRouter()
    router.register('user_details', UserDetailViewSet)
    urlpatterns = [path('api/', include(router.urls)), ...]
    

    UserDetailViewSet 必须在 api\views.py 中声明(api 是 DRF 应用的目录)

    from rest_framework.decorators import action
    from rest_framework import viewsets
    from rest_framework.response import Response
    
    class UserDetailViewSet(viewsets.ModelViewSet):
        queryset = UserDetail.objects.all()
        serializer_class = UserDetailSerializer
    
        @action(methods=['put'], detail=False)
        def filter_by_something(self, request):
            something = request.data.get('that_something')
            queryset = UserDetail.objects.filter(something__exact=something)
            return Response(self.get_serializer(queryset, many=True).data)
    

    然后你将在 http:\\your_website\api\user_details\filter_by_something 上发出 PUT 请求

    试试这样的。它应该工作!

    【讨论】:

    • 我在 URLs.py(项目文件夹)和 views.py(应用程序文件夹)中添加了代码,我必须在 serializers.py(应用程序文件夹)中创建一个新的序列化程序类,它的代码看起来像 @ 987654323@ 现在我应该在哪里以及如何在代码中添加 PUT 和 DELETE 请求代码?
    • 我收到一个错误in UserDetailViewSet queryset = UserDetail.objects.all() AttributeError: type object 'UserDetail' has no attribute 'objects'
    • UserDetail 是您的应用程序中声明的模型:class UserDetail(models.Model): ....。你可以像这样在 api\views.py 中导入它:from your_app.models import UserDetail。在你的情况下,我认为这不是 UserDetail,它只是用户
    • 我已经按照您的说法编辑了问题和代码,但是在 UserDetail 类 UserViewSet(viewsets.ModelViewSet) 中出现错误:NameError: name 'viewsets' is not defined 你能检查一下编辑过的代码吗我的问题?
    • 只需插入:from rest_framework import viewsets
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2012-09-02
    • 2018-12-20
    • 2015-09-12
    • 1970-01-01
    • 2017-05-22
    • 2017-11-09
    • 1970-01-01
    相关资源
    最近更新 更多