如何在使用Django Rest Framework的viewsets的post方法中在Swagger UI中传递参数,而不使用任何模型?

16 浏览
0 Comments

如何在使用Django Rest Framework的viewsets的post方法中在Swagger UI中传递参数,而不使用任何模型?

我需要做一个api来完成某种逻辑(例如:处理数据、生成词云、进行机器学习层...),并返回简单的状态。在我想要做的逻辑中,我不需要模型,只需接收一些参数的json并执行我想做的事情。

我已经创建了api视图,但我找不到在请求体中接收参数的方法。

我正在阅读一个设计我的方法的良好模式(Django Rest Framework Business Logic在django中分离业务逻辑和数据访问)并在api.py文件中编写了我的代码。我不使用序列化器处理此视图,因为我不需要从模型中消耗数据,而是使用输入的json。

api.py

from rest_framework import viewsets
from rest_framework import views
from rest_framework import status
from rest_framework.response import Response
from rest_framework_swagger.views import get_swagger_view
class WordCloudViewSet(viewsets.ViewSet):
    def create(self, request, *args, **kwargs):
        comments_list = kwargs['data']['comments']
        user_id = kwargs['data']['user_id']
        '''
        some logic
        '''
        return Response(status=status.HTTP_200_OK)

urls.py

from django.conf.urls import include, url
from rest_framework import routers
from .api import (WordCloudViewSet)
from api import views
router = routers.DefaultRouter()
schema_view = get_swagger_view(title='Swagger Documentation')
urlpatterns = [
    url(r'^api/wordcloud/', WordCloudViewSet.as_view({'get': 'list', 'post':'create'}), name='wordcloud')
]
urlpatterns += router.urls

我尝试在postman中发送带有body的json,如下所示:

{
    "data": {
        "comments": ["Lorem ipsum dolor sit amet"],
        "user_id": 1
    }
}

但args和kwargs都为空。即使在swagger UI中,我也看不到参数标签来发送我的json。

\"enter

我找到的所有示例都使用模型和序列化器。

一个简单的Api View接收一个并返回一个\"Hello\" + Name,对我来说就足够了。

如何在WordCloudViewSet中指定通过post请求的输入参数,而不使用模型?

感谢您的关注,并提前感谢您的回应。

编辑

意外的是,我还没有尝试使用request.data,并它能够起作用。然而,正如我之前所评论的,swagger UI无法测试我的api,因为它没有显示发送请求的输入标签。

admin 更改状态以发布 2023年5月20日
0
0 Comments

最后,我找到了一个简单的解决方案,只需要更改 URL,从这个:\n

urlpatterns = [
    url(r'^api/wordcloud/', WordCloudViewSet.as_view({'get': 'list', 'post':'create'}), name='wordcloud')
]

\n到这个: \n

urlpatterns = [
    url(r'^api/wordcloud/comments//user_id/', WordCloudViewSet.as_view({'get': 'list', 'post':'create'}), name='wordcloud')
]

\n然后在 Swagger 中,它会显示参数的标签:\n\"enter\n额外的信息就是,对于遇到同样问题的其他用户,我建议使用序列化器进行必填和可选参数验证,即使我不需要从 Model 中消耗数据。\n在 serializers.py 中:\n

class WordCloudAPISerializer(serializers.ModelSerializer):
    comments = serializers.CharField(required=True)
    user = serializers.IntegerField(source='id',required=False)
    class Meta:
        model = User
        fields = ('comments','user')
    def to_internal_value(self, data):
        required = []
        optionals = []
        for k in ['comments']:
            '''
            - Case 1: Is the k field in the data and it's empty?
            - Case 2: Is not the k field in the data?
            '''
            if (data.keys().__contains__(k) and data[k] == '') or (not data.keys().__contains__(k)):
                required.append(k)
        for k in ['user']:
            # Is not the k field in the data?
            if not data.keys().__contains__(k):
                optionals.append(k)
        if len(required) > 0 and len(optionals) > 0:
            raise ValueError("The following fields are required: %s" % ','.join(required) + " and the following fields are needed but can be empty: %s" % ','.join(optionals))
        elif len(required) > 0 and len(optionals) == 0:
            raise ValueError("The following fields are required: %s" % ','.join(required))
        elif len(required) == 0 and len(optionals) > 0:
            raise ValueError("The following fields are needed but can be empty: %s" % ','.join(optionals))
        return data

\n然后在 api.py 中:\n

            serializer = WordCloudAPISerializer(data=kwargs['data'])
            if serializer.is_valid():
                '''some logic'''
            else:
                return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

\n我希望这对其他人有用。

0