1 反序列化类校验部分源码解析
| |
| -视图类中的 ser.is_valid(),就会执行校验,校验通过返回True,不通过返回False |
| |
| |
| |
| def is_valid(self, *, raise_exception=False): |
| |
| if not hasattr(self, '_validated_data'): |
| try: |
| |
| self._validated_data = self.run_validation(self.initial_data) |
| except ValidationError as exc: |
| self._validated_data = {} |
| self._errors = exc.detail |
| else: |
| self._errors = {} |
| |
| if self._errors and raise_exception: |
| raise ValidationError(self.errors) |
| |
| return not bool(self._errors) |
| |
| -切记一定不要按住ctrl键点击 |
| -真正的执行顺序是,从下往上找,找不到,再往上 |
| -最终从Serializer类中找到了run_validation,而不是Field中的run_validation |
| def run_validation(self, data=empty): |
| |
| (is_empty_value, data) = self.validate_empty_values(data) |
| if is_empty_value: |
| return data |
| |
| value = self.to_internal_value(data) |
| try: |
| self.run_validators(value) |
| |
| value = self.validate(value) |
| |
| except (ValidationError, DjangoValidationError) as exc: |
| raise ValidationError(detail=as_serializer_error(exc)) |
| return value |
| |
| def to_internal_value(self, data): |
| ret = OrderedDict() |
| errors = OrderedDict() |
| fields = self._writable_fields |
| |
| for field in fields: |
| |
| validate_method = getattr(self, 'validate_' + field.field_name, None) |
| try: |
| |
| validated_value = validate_method(validated_value) |
| except ValidationError as exc: |
| errors[field.field_name] = exc.detail |
| else: |
| set_value(ret, field.source_attrs, validated_value) |
| if errors: |
| raise ValidationError(errors) |
| return ret |
| |
2 断言
| |
| name = 'lqz' |
| assert name=='lqz' |
| print('后续代码') |
3 drf之请求
3.1 Request能够解析的前端传入的编码格式
| |
| |
| renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES |
| parser_classes = api_settings.DEFAULT_PARSER_CLASSES |
| authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES |
| throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES |
| permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES |
| content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS |
| metadata_class = api_settings.DEFAULT_METADATA_CLASS |
| versioning_class = api_settings.DEFAULT_VERSIONING_CLASS |
| |
| |
| |
| class BookView(APIView): |
| parser_classes = [JSONParser,] |
| |
| |
| -django有套默认配置,每个项目有个配置 |
| -drf有套默认配置,每个项目也有个配置---》就在django的配置文件中 |
| REST_FRAMEWORK = { |
| 'DEFAULT_PARSER_CLASSES': [ |
| |
| 'rest_framework.parsers.FormParser', |
| |
| ], |
| } |
| |
| -只需要在视图类,配置3个即可 |
| -因为:先从视图类自身找,找不到,去项目的drf配置中找,再找不到,去drf默认的配置找 |
3.2 Request类有哪些属性和方法(学过)
https://www.cnblogs.com/bnmm/p/17086775.html
4 drf之响应
4.1 Response能够响应的编码格式
| |
| |
| -drf做了个判断,如果是浏览器,好看一些,如果是postman只要json数据 |
| |
| |
| |
| -两个响应类---》找---》drf的配置文件中找--》两个类 |
| -from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer |
| class BookView(APIView): |
| renderer_classes=[JSONRenderer,] |
| |
| |
| REST_FRAMEWORK = { |
| 'DEFAULT_RENDERER_CLASSES': [ |
| 'rest_framework.renderers.JSONRenderer', |
| 'rest_framework.renderers.BrowsableAPIRenderer', |
| ], |
| } |
| |
| |
| 优先使用视图类中的配置,其次使用项目配置文件中的配置,最后使用内置的 |
4.2 Resposne的源码属性或方法
| |
| -from rest_framework.response import Response |
| -视图类的方法返回时,retrun Response ,走它的__init__,init中可以传什么参数 |
| |
| |
| |
| def __init__(self, |
| data=None, |
| status=None, |
| template_name=None, |
| headers=None, |
| exception=False, |
| content_type=None) |
| |
| -data:之前咱们写的ser.data 可以是字典或列表,字符串---》序列化后返回给前端---》前端在响应体中看到的就是这个 |
| -status:http响应的状态码,默认是200,你可以改 |
| -drf在status包下,把所有http响应状态码都写了一遍,常量 |
| -from rest_framework.status import HTTP_200_OK |
| -Response('dddd',status=status.HTTP_200_OK) |
| |
| -template_name:了解即可,修改响应模板的样子,BrowsableAPIRenderer定死的样子,后期公司可以自己定制 |
| -headers:响应头,http响应的响应头 |
| -考你,原生djagno,如何像响应头中加东西 |
| |
| obj = HttpResponse('dddd') |
| obj['xxc'] = 'yyc' |
| return obj |
| -content_type :响应编码格式,一般不动 |
| |
5 视图组件介绍及两个视图基类
| |
| |
| |
| -传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象; |
| -视图方法可以返回REST framework的Response对象- |
| -任何APIException异常都会被捕获到,并且处理成合适的响应信息; |
| -在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制 |
| |
| |
| |
| APIVIew |
| -类属性: |
| renderer_classes |
| parser_classes |
| authentication_classes |
| throttle_classes |
| permission_classes |
| -基于APIView+ModelSerializer+Resposne写5个接口 |
| -详见代码 |
5.1 APIView+ModelSerializer+Resposne写5个接口
5.1.1 视图类
| from .models import Book |
| from .serializer import BookSerializer |
| |
| |
| class BookView(APIView): |
| def get(self, request): |
| books = Book.objects.all() |
| ser = BookSerializer(instance=books, many=True) |
| return Response(ser.data) |
| |
| def post(self, request): |
| ser = BookSerializer(data=request.data) |
| if ser.is_valid(): |
| ser.save() |
| |
| return Response({'code': 100, 'msg': '新增成功', 'result': ser.data}) |
| else: |
| return Response({'code': 101, 'msg': ser.errors}) |
| |
| |
| class BookDetailView(APIView): |
| def get(self, request, pk): |
| books = Book.objects.filter(pk=pk).first() |
| ser = BookSerializer(instance=books) |
| return Response(ser.data) |
| |
| def put(self, request, pk): |
| books = Book.objects.filter(pk=pk).first() |
| ser = BookSerializer(instance=books, data=request.data) |
| if ser.is_valid(): |
| ser.save() |
| return Response({'code': 100, 'msg': '修改成功', 'result': ser.data}) |
| else: |
| return Response({'code': 101, 'msg': ser.errors}) |
| |
| def delete(self, request, pk): |
| Book.objects.filter(pk=pk).delete() |
| return Response({'code': 100, 'msg': '删除成功'}) |
5.1.2 序列化类
| |
| class BookSerializer(serializers.ModelSerializer): |
| |
| class Meta: |
| model = Book |
| fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors'] |
| extra_kwargs = {'name': {'max_length': 8}, |
| 'publish_detail': {'read_only': True}, |
| 'author_list': {'read_only': True}, |
| 'publish': {'write_only': True}, |
| 'authors': {'write_only': True}, |
| } |
5.5.3 路由
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| path('books/', views.BookView.as_view()), |
| path('books/<int:pk>/', views.BookDetailView.as_view()), |
| ] |
6 基于GenericAPIView+5个视图扩展类
6.1 视图类
| from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, \ |
| ListModelMixin |
| |
| |
| |
| |
| class BookView(GenericAPIView, ListModelMixin, CreateModelMixin): |
| queryset = Book.objects.all() |
| serializer_class = BookSerializer |
| |
| def get(self, request): |
| return self.list(request) |
| |
| def post(self, request): |
| return self.create(request) |
| |
| |
| class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): |
| queryset = Book.objects.all() |
| serializer_class = BookSerializer |
| |
| def get(self, request, *args, **kwargs): |
| return self.retrieve(request, *args, **kwargs) |
| |
| def put(self, request, *args, **kwargs): |
| return self.update(request, *args, **kwargs) |
| |
| def delete(self, request, *args, **kwargs): |
| return self.destroy(request, *args, **kwargs) |
6.2 视图类
| class BookSerializer(serializers.ModelSerializer): |
| |
| class Meta: |
| model = Book |
| fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors'] |
| extra_kwargs = {'name': {'max_length': 8}, |
| 'publish_detail': {'read_only': True}, |
| 'author_list': {'read_only': True}, |
| 'publish': {'write_only': True}, |
| 'authors': {'write_only': True}, |
| } |
6.3 路由
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| path('books/', views.BookView.as_view()), |
| path('books/<int:pk>/', views.BookDetailView.as_view()), |
| ] |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?