首页 文章

用于通用视图的Django REST API自定义方法

提问于
浏览
0

我是实习生,正在开发一个项目,我开发的DRF API需要与我的同事用Ionic框架编写的移动应用程序进行交互 . 我们正在创造新用户 . 我的查看方法如下:

class NewUser(generics.CreateAPIView):
    model = User
    permission_classes = [permissions.AllowAny]
    serializer_class = NewUserSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        token, created = Token.objects.get_or_create(user=serializer.instance)
        return Response({'token': token.key}, status=status.HTTP_201_CREATED, headers=headers)

当有人想要通过POST请求创建新用户时如果尚未使用用户名,那么API将返回201状态代码和JSON中的令牌,如果用户名已经获取,则返回400状态和JSON中的错误消息 . 我的同事要求我在尝试创建名称已存在的用户名时将状态消息更改为200 . 他说他不能消耗ERROR反应 . 他的代码看起来像:

$http.post(url,{
username:$scope.tel,
password:$scope.passwd
}).success(function(data){
alert(data);
$ionicLoading.hide();
console.log(data);
})

问题:1)我是否应该调整我的API以发送200状态而不是更多逻辑400用于'用户已注册'错误?我试图更改我的代码,但我找不到在DRF的CreateAPIView / ModelSerializer中覆盖的方法 . 我最终将我的视图类重写为方法:

@api_view(['POST'])
def newUser(request):
    """
    Saves a new user on the database
    """
    if request.method == 'POST':

        serializer = NewUserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            token, created = Token.objects.get_or_create(user=serializer.instance)
            return Response({'token': token.key}, status=status.HTTP_201_CREATED, headers=serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_200_OK)

问题:2)如果我想改变API的行为和响应,我应该覆盖哪种方法3)我是Django的新手,并且仍然不知道我们应该在哪里使用通用视图VS. @.... 方法

1 回答

  • 0

    在这种情况下,200比400主要是偏好 . 400表示“错误请求” . 对于格式不正确的请求,这通常更正确,而不是不满足某些条件的请求 .

    200恰当地传达了正确的信息:

    您的请求有效,但我没有创建新记录 .

    至于如何进行覆盖 . 最短路径是覆盖 CreateAPIView.create 并更改使用的响应代码 . 您还应该通过调用 super 来避免重复 CreateAPIView 的默认行为 .

    class CreateUserView(generics.CreateAPIView):
        model = User
        permission_classes = [permissions.AllowAny]
        serializer_class = NewUserSerializer
    
        def create(self, request, *args, **kwargs):
            response = super(CreateUserView, self).create(request, *args, **kwargs)
            token, created = Token.objects.get_or_create(user=serializer.instance)
            response.status = status.HTTP_200_OK
            response.data = {'token': token.key}
            return response
    

    就个人而言,我本来也会设计我的 NewUserSerializer 有一个令牌字段并处理令牌所以我没有必要在 View 中做这项工作 . 它不属于 View .

相关问题