首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我们可以在APIView(django rest framework)中使用serializer_class属性吗?

我们可以在APIView(django rest framework)中使用serializer_class属性吗?
EN

Stack Overflow用户
提问于 2016-08-28 05:29:44
回答 2查看 5.1K关注 0票数 12

根据DRF文档,在使用GenericAPIView时应设置serializer_class属性。但是为什么serializer_class属性还要与APIView一起使用呢

下面是我的API代码:

代码语言:javascript
复制
class UserView(APIView):

    serializer_class = SignupSerializer

    @transaction.atomic
    def post(self, request):
        email = get_data_param(request, 'email', None)
        password = get_data_param(request, 'password', None)

        params = request.POST.copy()
        params["username"] = email

        serializer = UserSerializer(data=params)
        if serializer.is_valid(raise_exception=True):
            user = serializer.save()
            user.set_password(password)
            user.save()
            params["user"] = user.id

        serializer = CustomProfileSerializer(data=params)
        if serializer.is_valid(raise_exception=True):
            profile = serializer.save()
            return Response(response_json(True, profile.to_dict(), None))

class SignupSerializer(serializers.Serializer):
    email = serializers.EmailField(max_length=100)
    password = serializers.CharField(max_length=50)

当我在浏览器中浏览此API时,它确实将emailpassword字段显示为输入,但是如果我不设置此serializer_class属性,则不会显示任何输入字段。

理想情况下,此serializer_class属性不应与APIView一起使用。我已经搜索了很多,但没有任何与此相关的可用信息。

有没有人能对这种行为做出解释?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2021-11-02 18:52:05

我想这对你有帮助。

创建serializer.py并编写:

代码语言:javascript
复制
from rest_framework import serializers

from .models import User


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('email', 'password')

和views.py:

代码语言:javascript
复制
from rest_framework.response import Response
from rest_framework.views import APIView

from .serializers import UserSerializer
from .models import User


class AddUserAPIView(APIView):
    def post(self, request):
        user_serializer = UserSerializer(data=request.data)
        if user_serializer.is_valid():
            user = user_serializer.save() 
            user.set_password(user_serializer.data["password"])
            return Response({'message': 'user added successfully!'})

        return Response({'message': user_serializer.errors})
票数 1
EN

Stack Overflow用户

发布于 2021-11-05 12:03:45

你说的完全正确!!

APIView (默认情况下)不使用serializer_class,因为它并不是用来处理任何请求处理逻辑的!

但是发生的情况是,用于在浏览器中呈现BrowsableAPIRenderer的API检查serializer_class属性,并将其设置为视图序列化程序(如果存在)。我们可以在BrowsableAPIRenderer代码中看到这点:

  1. 渲染器的_get_serializer类:

def _get_serializer(self,serializer_class,view_instance,request,*args,**kwargs):kwargs‘’context‘={ 'request':request,'format':self.format,'view':view_instance } return serializer_class(*args,**kwargs)

get_rendered_html_form中的

  1. 以及用于设置呈现程序序列化程序(如果存在)的方法

代码语言:javascript
复制
- [Line 483](https://github.com/encode/django-rest-framework/blob/00cd4ef864a8bf6d6c90819a983017070f9f08a5/rest_framework/renderers.py#L483): `has_serializer_class = getattr(view, 'serializer_class', None)`
代码语言:javascript
复制
- [Lines 497 to 509](https://github.com/encode/django-rest-framework/blob/00cd4ef864a8bf6d6c90819a983017070f9f08a5/rest_framework/renderers.py#L497):

if has_serializer: if method in ('PUT','PATCH'):serializer = view.get_serializer(instance=instance,**kwargs) else: serializer = view.get_serializer(**kwargs) else:#此时我们必须在('PUT','PATCH'):serializer_class if method in (‘PUT’,‘PATCH’):serializer = self._get_serializer(view.serializer_class,view,request,instance=instance,**kwargs) else:串行器= self._get_serializer(view.serializer_class,视图,请求,**kwargs)

本质上,您意外地通过提供serializer_class属性覆盖了BrowserAPIRenderer关于APIView的默认行为。

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

https://stackoverflow.com/questions/39185912

复制
相关文章

相似问题

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