0 drf整体内容
| |
| -web开发模式 |
| -api接口 |
| -接口测试工具 |
| -restful规范 |
| -序列化反序列化 |
| -drf快速使用 |
| -APIView, Request类 |
| -drf把django的好多东西重写了 |
| |
| |
| -基本序列化类 |
| -模型类序列化类 |
| -如何序列化 |
| -如何反序列化 |
| -反序列化的数据校验功能 |
| |
| |
| -drf的request已经不是原来django的request了 |
| -drf的response已经不是原来django的response了 |
| -指定可以接收请求的编码方式 |
| -指定响应格式 |
| |
| |
| |
| -两个视图基类 |
| -5个视图扩展类 |
| -9个视图子类 |
| -视图集 |
| |
| |
| |
| -自动生成路由 |
| |
| |
| |
| |
| |
| |
| |
| |
| ---------------------- |
| |
| |
| |
1 APIView执行流程
1.1基于APIView+JsonResponse编写接口
| |
| |
| |
| from rest_framework.views import APIView |
| from django.http import JsonResponse |
| |
| class BookView(APIView): |
| def get(self, request): |
| books = Book.objects.all() |
| book_list = [] |
| for book in books: |
| book_list.append({'name': book.name, 'price': book.price, 'publish': book.publish}) |
| |
| return JsonResponse(book_list, safe=False) |
1.2基于APIView+Response编写接口
| from rest_framework.response import Response |
| |
| class BookView(APIView): |
| def get(self, request): |
| books = Book.objects.all() |
| book_list = [] |
| for book in books: |
| book_list.append({'name': book.name, 'price': book.price, 'publish': book.publish}) |
| |
| return Response(book_list) |
| |
| |
| |
| |
1.3 APIView的执行流程
| |
| views.BookView.as_view()),---》请求来了,执行views.BookView.as_view()()----->现在的as_view是APIView的as_view |
| |
| |
| @classmethod |
| def as_view(cls, **initkwargs): |
| |
| |
| view = super().as_view(**initkwargs) |
| |
| |
| return csrf_exempt(view) |
| |
| |
| |
| def dispatch(self, request, *args, **kwargs): |
| |
| |
| request = self.initialize_request(request, *args, **kwargs) |
| |
| |
| |
| |
| self.request = request |
| try: |
| |
| self.initial(request, *args, **kwargs) |
| |
| |
| if request.method.lower() in self.http_method_names: |
| handler = getattr(self, request.method.lower(), |
| self.http_method_not_allowed) |
| else: |
| handler = self.http_method_not_allowed |
| |
| response = handler(request, *args, **kwargs) |
| |
| except Exception as exc: |
| |
| response = self.handle_exception(exc) |
| self.response = self.finalize_response(request, response, *args, **kwargs) |
| return self.response |
| |
| |
| |
| |
| |
| def auth() |
| |
| def add() |
| |
| |
| @auth |
| def add() |
| |
| |
1.3APIView的执行流程总结
| |
| 1 去除了所有的csrf |
| 2 包装了新的request, 以后再视图类中用的request是新的request Request类的对象, 不是原生的了 |
| -原生的在: 新的requests._request |
| 3 在执行视图类的方法之前, 执行了3大认证、 |
| 4 如果在3大认证或视图函数方法执行过程中出了错, 会有异常捕获----> 全局异常捕获 |
| 5 以后视图类方法中的request都是新的 |
2 Request对象源码分析
| |
| |
| |
| -新的 request._request 老的 |
| |
| |
| -方法 __getattr__ |
| -在视图类的方法中,执行request.method ,新的request是没有method的,就触发了新的Request的__getattr__方法的执行 |
| def __getattr__(self, attr): |
| try: |
| |
| return getattr(self._request, attr) |
| except AttributeError: |
| return self.__getattribute__(attr) |
| |
| |
| -request.data--->这是个方法,包装成了数据属性 |
| -以后无论post,put。。放在body中提交的数据,都从request.data中取,取出来就是字典 |
| -无论是那种编码格式 |
| |
| |
| -request.query_params--->这是个方法,包装成了数据属性 |
| -get请求携带的参数,以后从这里面取 |
| -query_params:查询参数--->restful规范请求地址中带查询参数 |
| |
| |
| -request.FILES--->这是个方法,包装成了数据属性 |
| -前端提交过来的文件,从这里取 |
| |
| |
| |
| |
| |
| -1 新的request用起来, 跟之前一模一样,因为新的取不到,会取老的__getattr__ |
| -2 request.data 无论什么编码 什么请求方式, 只要是body中的数据, 就从这里取, 字典 |
| -3 request.query_params 就是原来的request._request.GET |
| -4 上传的文件从request.FILES |
| |
| |
| |
| -__str__: 打印对象会调用 |
| -__init__:类() 会调用 |
| -__call__: 对象() 会调用 |
| -__new__: |
| -__getattr__: 对象.属性, 如果属性不存在, 会触发它的执行 |
3 序列化器介绍和快速使用
| |
| |
| |
| -以后咱们只需要写自己的类, 继承drf提供的序列化类, 使用其中的某些方法, 就能完成上面的操作 |
| |
| |
| |
3.1序列化类基本使用 , 序列化多条
serializer.py--BookSerializer类
| from rest_framework import serializers |
| |
| class BookSerializer(serializers.Serializer): |
| |
| name = serializers.CharField() |
| |
| publish = serializers.CharField() |
views.py--->BookView类
| class BookView(APIView): |
| def get(self, request): |
| |
| print(request.method) |
| print(request._request) |
| print(type(self.request)) |
| |
| book = Book.objects.all() |
| |
| |
| |
| ser = BookSerializer(instance=books, many=True) |
| return Response(ser.data) |
3.1序列化单条
序列化类---没有动
| from rest_framework import serializers |
| |
| class BookSerializer(serializers.Serializer): |
| |
| name = serializers.CharField() |
| price = serializers.CharField() |
| publish = serializers.CharField() |
视图类---》BookDetailView
| class BookDetailView(APIView): |
| |
| def get(self, request, *args, **kwargs): |
| book = Book.objects.filter(pk=kwargs.get('pk')).first() |
| |
| ser = BookSerializer(instance=book) |
| return Response(ser.data) |
url加了新的路由
| urlpatterns = [ |
| path('books/<int:pk>/', views.BookDetailView.as_view()), |
| ] |
4 反序列化
4.1 反序列化的新增
| class BookSerializer(serializers.Serializer): |
| |
| name = serializers.CharField() |
| price = serializers.CharField() |
| publish = serializers.CharField() |
| |
| def create(self, validated_data): |
| |
| |
| |
| book = Book.objects.create(**validated_data) |
| |
| return book |
视图类
| class BookView(APIView): |
| 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}) |
4.2反序列化的修改
序列化类
| class BookSerializer(serializers.Serializer): |
| |
| name = serializers.CharField() |
| price = serializers.CharField() |
| publish = serializers.CharField() |
| |
| def create(self, validated_data): |
| |
| |
| |
| book = Book.objects.create(**validated_data) |
| |
| return book |
| |
| def update(self, instance, validated_data): |
| |
| |
| instance.name = validated_data.get('name') |
| instance.price = validated_data.get('price') |
| instance.publish = validated_data.get('publish') |
| instance.save() |
| |
| return instance |
视图类
| class BookDetailView(APIView): |
| |
| |
| def put(self, request, pk): |
| book = Book.objects.filter(pk=pk).first() |
| |
| ser = BookSerializer(data=request.data, instance=book) |
| if ser.is_valid(): |
| ser.save() |
| return Response({'code': 100, 'msg': '修改成功', 'result': ser.data}) |
| else: |
| return Response({'code': 101, 'msg': ser.errors}) |
4.3 删除单条
视图类
| class BookDetailView(APIView): |
| |
| def delete(self, requset, pk): |
| Book.objects.filter(pk=pk).delete() |
| return Response({'code': 100, 'msg': '删除成功'}) |
5 序列化的校验
| |
| -局部钩子 |
| -全局钩子 |
| |
| |
| class BookSerializer(serializers.Serializer): |
| |
| name = serializers.CharField() |
| price = serializers.CharField() |
| publish = serializers.CharField() |
| |
| def create(self, validated_data): |
| |
| |
| |
| book = Book.objects.create(**validated_data) |
| |
| return book |
| |
| def update(self, instance, validated_data): |
| |
| |
| instance.name = validated_data.get('name') |
| instance.price = validated_data.get('price') |
| instance.publish = validated_data.get('publish') |
| instance.save() |
| |
| return instance |
| |
| |
| |
| def validate_name(self, name): |
| |
| if name.startswith('sb'): |
| |
| raise ValidationError('不能以sb开头') |
| else: |
| return name |
| |
| |
| def validate(self, attrs): |
| |
| if attrs.get('name') == attrs.get('publish'): |
| raise ValidationError('书名跟出版社名字不能一致') |
| else: |
| return attrs |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构