1 APIView执行流程
1.1 基于APIView+JsonResponse编写接口
models
| from django.db import models |
| |
| class Publish(models.Model): |
| name=models.CharField(max_length=32) |
| address=models.CharField(max_length=32) |
| phone=models.CharField(max_length=32) |
views
| |
| |
| from django.http import JsonResponse |
| from rest_framework.views import APIView |
| from .models import Publish |
| class Publishview(APIView): |
| def get(self,request): |
| publishs=Publish.objects.all() |
| publish_list=[] |
| for publish in publishs: |
| publish_list.append({'name':publish.name,'address':publish.address,'phone':publish.phone}) |
| |
| return JsonResponse(publish_list,safe=False) |
| |
url
| path('publish/',views.Publishview.as_view()), |
1.2 基于APIView+Response 写接口
| from rest_framework.views import APIView |
| from .models import Publish |
| from rest_framework.response import Response |
| class Publishview(APIView): |
| def get(self,request): |
| publishs=Publish.objects.all() |
| publish_list=[] |
| for publish in publishs: |
| publish_list.append({'name':publish.name,'address':publish.address,'phone':publish.phone}) |
| return Response(publish_list) |
1.3 APIView的执行流程
| |
| |
| @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 |
| |
| 1 去除了所有的csrf |
| 2 包装了新的request,以后在视图类中用的request是新的request Request类的对象,不是原生的了 |
| -原生的在:新的requets._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 序列化类基本使用,序列化多条
| from app01.serializer import PublishSerializer |
| class Publishview(APIView): |
| def get(self,request): |
| publishs=Publish.objects.all() |
| res=PublishSerializer(instance=publishs,many=True) |
| return Response(res.data) |
3.2 序列化单条
序列化类---没有动
views
| class PublishDetailView(APIView): |
| def get(self,request,**kwargs): |
| publish=Publish.objects.filter(pk=kwargs.get('pk')).first() |
| res=PublishSerializer(instance=publish) |
| return Response(res.data) |
url
| path('publish/<int:pk>/',views.PublishDetailView.as_view()) |
4 反序列化
4.1 反序列化的新增和修改
序列化类
serializer
| from rest_framework import serializers |
| from .models import Publish |
| class PublishSerializer(serializers.Serializer): |
| name=serializers.CharField() |
| address=serializers.CharField() |
| phone=serializers.CharField() |
| def create(self, validated_data): |
| publish=Publish.objects.create(**validated_data) |
| return publish |
| def update(self, instance, validated_data): |
| |
| |
| instance.name=validated_data.get('name') |
| instance.address=validated_data.get('address') |
| instance.phone=validated_data.get('phone') |
| instance.save() |
| return instance |
view
| class PublishView(APIView): |
| def get(self,request): |
| publishs=Publish.objects.all() |
| res=PublishSerializer(instance=publishs,many=True) |
| return Response(res.data) |
| def post(self,request): |
| res=PublishSerializer(data=request.data) |
| if res.is_valid(): |
| res.save() |
| return Response({'code':100,'msg':res.data}) |
| else: |
| return Response({'code':101,'msg':res.errors}) |
| class PublishDetailView(APIView): |
| def get(self,request,**kwargs): |
| publish=Publish.objects.filter(pk=kwargs.get('pk')).first() |
| res=PublishSerializer(instance=publish) |
| return Response(res.data) |
| def put(self,request,**kwargs): |
| publish=Publish.objects.filter(pk=kwargs.get('pk')).first() |
| ser=PublishSerializer(data=request.data,instance=publish) |
| if ser.is_valid(): |
| ser.save() |
| return Response({'code': 100, 'msg': ser.data}) |
| else: |
| return Response({'code': 101, 'msg': ser.errors}) |
4.2删除单条
| class PublishDetailView(APIView): |
| def delete(self,request,**kwargs): |
| Publish.objects.filter(pk=kwargs.get('pk')).delete() |
| return Response({'code':100,'msg':'删除成功'}) |
5 反序列化的校验
| from rest_framework import serializers |
| from rest_framework.exceptions import ValidationError |
| |
| from .models import Publish |
| class PublishSerializer(serializers.Serializer): |
| name=serializers.CharField() |
| address=serializers.CharField() |
| phone=serializers.CharField() |
| def create(self, validated_data): |
| publish=Publish.objects.create(**validated_data) |
| return publish |
| def update(self, instance, validated_data): |
| |
| |
| instance.name=validated_data.get('name') |
| instance.address=validated_data.get('address') |
| instance.phone=validated_data.get('phone') |
| instance.save() |
| return instance |
| |
| def validate_name(self,name): |
| if name.startswith('11'): |
| raise ValidationError('不可以11开头') |
| else: |
| return name |
| |
| def validate(self, attrs): |
| if attrs.get('name')==attrs.get('phone'): |
| raise ValidationError('名字不能和手机和相同') |
| else: |
| return attrs |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?