Python APIView POST方法中Django Rest框架验证

Python APIView POST方法中Django Rest框架验证,python,django,python-3.x,django-rest-framework,drf-queryset,Python,Django,Python 3.x,Django Rest Framework,Drf Queryset,我是DRF新手,正在尝试构建rest api,我需要为任务执行创建一个api,而不仅仅是CRUD,这就是为什么我覆盖了APIView的POST方法,如下所示: class DeploymentsList(viewsets.ModelViewSet): queryset = DeploymentOnUserModel.objects.all() serializer_class = DeploymentonUserSerializer def create(self, r

我是DRF新手,正在尝试构建rest api,我需要为任务执行创建一个api,而不仅仅是CRUD,这就是为什么我覆盖了APIView的POST方法,如下所示:

class DeploymentsList(viewsets.ModelViewSet):
    queryset = DeploymentOnUserModel.objects.all()
    serializer_class = DeploymentonUserSerializer

    def create(self, request, *args, **kwargs):
        """overwrite this for extra actions"""
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid(raise_exception=True):
            print('valid request')
            serializer.save()
            return Response(serializer.data)
        else:
            print('Something invalid')
            return Response('Invalid request')
models.py:

serializers.py:

URL.py:

但我不知道如何验证请求?当我重写APIView的POST方法时

发布数据:


}

您可以像下面这样使用
ListCreateAPIView
。我们也可以在
url.py
中直接使用
ListCreateAPIView

序列化程序.py

views.py

您的答案错误修复

def create(self, request, *args, **kwargs):
    """overwrite this for extra actions"""
    serializer = self.serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data)

参考资料:

您想要实现什么还不是很清楚

我想说的是,您希望在收到请求并验证输入数据后执行其他任务

虽然不确定要执行的任务类型和时间-在保存模型之前或之后

但在创建模型之前,您可以这样做:

 def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)

     **.... your task - access to data via serializer.validated_data....**

    self.perform_create(serializer)        
    return Response(serializer.data)
或者,如果您想在创建模型后执行某些操作,您可以覆盖perform_create(正如我们从create方法的实现中看到的,在验证输入之后,会调用它)

已更新以解决“AttributeError:'str'对象没有属性'values'的问题”

问题在于您使用viewset时-viewset提供了一个“资源控制视图”,您可以使用该视图列出、检索、更新和删除资源

您不需要在urlconf中显式注册视图,以便进行列表/创建,然后进行详细信息

相反,使用router类执行此操作,它将为您提供所有视图(包括详细信息):

现在你可以做:

  • 获取部署/
  • 部署后
  • 获取部署/{id}->详细信息
您遇到的另一个问题是验证。我不建议在模型的保存函数中引发ValidationError

有一个序列化程序来处理您的验证,您可以在DeploymentUserSerializer中的validate函数中执行此操作

def validate(self, attrs):
    # perform your validation here
    return attrs

您需要验证什么?序列化程序用于验证Hi@SaeedBabashahi,我需要验证传入的数据,我如何在这里使用序列化程序?阅读Hi@Anjaneyulubata的文档,我需要覆盖post请求。@AbdulRehman序列化程序将自动验证
post
数据。为什么要重写
POST
方法?因为我需要获取请求数据并对其进行解析以供进一步执行,所以它将自动返回从
request.data
中获取的
serializer.data
。请参阅如何使用
url
,因为现在它返回:raise TypeError(当“TypeError:调用视图集上的
.as_view()
时,必须提供
操作
参数。例如
.as_视图({'get':'list')
这是另一回事。有关此信息,请查看DRF文档中的路由器()
Internal Server Error: /api/v1/deployments/
Traceback (most recent call last):
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/viewsets.py", line 95, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
    response = self.handle_exception(exc)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/views.py", line 454, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/views.py", line 491, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/abdul/PycharmProjects/KontainerApi/deployments/apiview.py", line 15, in create
    serializer.is_valid(raise_exception=False)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/serializers.py", line 236, in is_valid
    self._validated_data = self.run_validation(self.initial_data)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/serializers.py", line 435, in run_validation
    value = self.to_internal_value(data)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/serializers.py", line 459, in to_internal_value
    fields = self._writable_fields
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/django/utils/functional.py", line 36, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/abdul/KontainerApi/lib/python3.6/site-packages/rest_framework/serializers.py", line 370, in _writable_fields
    field for field in self.fields.values()
AttributeError: 'str' object has no attribute 'values'
[27/Jun/2018 16:11:41] "POST /api/v1/deployments/ HTTP/1.1" 500 15073
  {
"deployment_name": "dep5",
"credentials": "cre4",
"project_name": "pro4",
"project_id": "004",
"cluster_name": "clus4",
"zone_region": "zon4",
"services": "Single",
"configuration": "conf4",
"routing": "route4"
from rest_framework import serializers
from .models import DeploymentOnUserModel

class DeploymentOnUserModelSerializer(serializers.ModelSerializer)
    class Meta:
        model = DeploymentOnUserModel
        fields = [
            'deployment_name', 'credentials', 'project_name', 
            'project_id', 'cluster_name', 'zone_region', 'services',
            'configuration', 'routing']
from rest_framework.generics import ListCreateAPIView
from .models import DeploymentOnUserModel
from .serializers import DeploymentOnUserModelSerializer 

class DeploymentsList(ListCreateAPIView):
     queryset = DeploymentOnUserModel.objects.all()
     serializer_class = DeploymentOnUserModelSerializer
def create(self, request, *args, **kwargs):
    """overwrite this for extra actions"""
    serializer = self.serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data)
 def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)

     **.... your task - access to data via serializer.validated_data....**

    self.perform_create(serializer)        
    return Response(serializer.data)
def perform_create(self, serializer):
    instance =  serializer.save()
     .... your task ....
router = DefaultRouter()
router.register(r'deployment', DeploymentsList, base_name='deployment')
urlpatterns = router.urls
def validate(self, attrs):
    # perform your validation here
    return attrs