首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用APIView和django-rest-swagger时为POST请求指定参数?

如何在使用APIView和django-rest-swagger时为POST请求指定参数?
EN

Stack Overflow用户
提问于 2016-12-12 15:55:03
回答 3查看 9K关注 0票数 14

在Django的最新版本中,REST Swagger (2.1.0)已不再推荐YAML文档字符串。我不能昂首阔步地显示POST请求参数。

这是我的看法

代码语言:javascript
复制
class UserAuthenticationView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = UserAuthenticationSerializer(data=self.request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            return Response({'token': user.auth_token.key}, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)

这是我的序列化器

代码语言:javascript
复制
class UserAuthenticationSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        if username and password:
            user = authenticate(username=username, password=password)
            if user:

                if not user.is_active:
                    msg = 'User account is disabled.'
                    raise serializers.ValidationError(msg, code='authorization')

            else:
                msg = 'Unable to log in with provided credentials.'
                raise serializers.ValidationError(msg, code='authorization')

        else:
            msg = 'Must include "username" and "password".'
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

这就是我所得到的

我没有得到包含POST数据字段的表单。我怎么弄到那个?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-12 20:27:44

这是rest框架获取模式代码(其中的一部分):

代码语言:javascript
复制
def get_serializer_fields(self, path, method, view):
    """
    Return a list of `coreapi.Field` instances corresponding to any
    request body input, as determined by the serializer class.
    """
    if method not in ('PUT', 'PATCH', 'POST'):
        return []

    if not hasattr(view, 'get_serializer'):
        return []

    serializer = view.get_serializer()

    if isinstance(serializer, serializers.ListSerializer):
        return [
            coreapi.Field(
                name='data',
                location='body',
                required=True,
                type='array'
            )
        ]
...

如您所见,如果您在视图中定义了get_serializer方法,它应该会工作,这将返回UserAuthenticationSerializer

-编辑--

忘记:快乐的编码。

票数 5
EN

Stack Overflow用户

发布于 2017-05-19 09:56:50

django-rest-swagger使用rest_framework.schemas.SchemaGenerator生成架构,SchemaGenerator使用get_serializer_fields获取视图的序列化器信息。get_serializer检查视图是否有生成表单的get_serializer_fields方法。GenericAPIView提供了get_serializer,因此从它继承就足够了。

GenericAPIView继承视图,而不是简单的APIView。并使用适当的序列化程序添加serializer_class属性。

代码语言:javascript
复制
from rest_framework.generics import GenericAPIView 

class UserAuthenticationView(GenericAPIView):

    serializer_class = UserAuthenticationSerializer

    def post(self, request, *args, **kwargs):
        serializer = UserAuthenticationSerializer(data=self.request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            return Response({'token': user.auth_token.key}, status=status.HTTP_200_OK)    
        return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
票数 28
EN

Stack Overflow用户

发布于 2018-08-23 06:29:00

使用django-rest-swagger==2.2.0的自定义ViewSet的工作示例:

代码语言:javascript
复制
from rest_framework import viewsets
from rest_framework.schemas import AutoSchema
from rest_framework.compat import coreapi, coreschema
from rest_framework.decorators import action


class DeviceViewSchema(AutoSchema):
    """
    Schema customizations for DeviceViewSet
    """

    def get_manual_fields(self, path, method):
        extra_fields = []
        if path.endswith('/send_command/'):
            extra_fields = [
                coreapi.Field(
                    "command",
                    required=True,
                    location="form",
                    schema=coreschema.String()
                ),
                coreapi.Field(
                    "params",
                    required=False,
                    location="form",
                    schema=coreschema.String()
                ),
            ]
        manual_fields = super().get_manual_fields(path, method)
        return manual_fields + extra_fields


class DeviceViewSet(viewsets.ViewSet):
    lookup_field = 'channel'
    lookup_value_regex = '[\w-]+'

    schema = DeviceViewSchema()

    @action(methods=['post'], detail=True, url_name='send_command')
    def send_command(self, request, channel):
        """
        Send command to device

        Parameters:
        - command: string
        - params: string (JSON encoded list or dict)
        """
        ...

最终结果是:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41104615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档