根据DRF文档,在使用GenericAPIView时应设置serializer_class属性。但是为什么serializer_class属性还要与APIView一起使用呢
下面是我的API代码:
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时,它确实将email和password字段显示为输入,但是如果我不设置此serializer_class属性,则不会显示任何输入字段。
理想情况下,此serializer_class属性不应与APIView一起使用。我已经搜索了很多,但没有任何与此相关的可用信息。
有没有人能对这种行为做出解释?谢谢。
发布于 2021-11-02 18:52:05
我想这对你有帮助。
创建serializer.py并编写:
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password')和views.py:
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})发布于 2021-11-05 12:03:45
你说的完全正确!!
APIView (默认情况下)不使用serializer_class,因为它并不是用来处理任何请求处理逻辑的!
但是发生的情况是,用于在浏览器中呈现BrowsableAPIRenderer的API检查serializer_class属性,并将其设置为视图序列化程序(如果存在)。我们可以在BrowsableAPIRenderer代码中看到这点:
_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中的
- [Line 483](https://github.com/encode/django-rest-framework/blob/00cd4ef864a8bf6d6c90819a983017070f9f08a5/rest_framework/renderers.py#L483): `has_serializer_class = getattr(view, 'serializer_class', None)`- [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的默认行为。
https://stackoverflow.com/questions/39185912
复制相似问题