drf基础
1. 序列化过程
子应用里面的路由
from django.urls import path, re_path from . import views urlpatterns = [ path("student/", views.StudentView.as_view()) ]
总路由
from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path("student/",include("students.urls")), path("sers/",include("sers.urls")), ]
模型类
from django.db import models # Create your models here. class Student(models.Model): # 表字段声明 # 字段名=models.数据类型(字段约束) name = models.CharField(null=False, max_length=32, verbose_name="姓名") sex = models.BooleanField(default=True, verbose_name="性别") age = models.IntegerField(verbose_name="年龄") class_num = models.CharField(max_length=5, verbose_name="班级编号") description = models.TextField(max_length=1000, verbose_name="个性签名") # 表信息 class Meta: # 设置表名 db_table="tb_students" verbose_name="学生" verbose_name_plural=verbose_name # 模型的操作方法 def __str__(self): return self.name
定义的序列化器
from rest_framework import serializers class StudentSerializers(serializers.Serializer): name = serializers.CharField() age = serializers.IntegerField() sex = serializers.BooleanField()
视图
from django.views import View from django.http.response import JsonResponse, HttpResponse from .serializers import StudentSerializers from students import models class StudentView(View): def get(self, request): # student_list = models.Student.objects.all() student_list = models.Student.objects.filter(pk=1) serializer = StudentSerializers(instance=student_list, many=True) print(serializer.data) return HttpResponse("ok")
2. 反序列化过程
子应用里面的路由
from django.urls import path, re_path from . import views urlpatterns = [ path("student/", views.StudentView.as_view()) ]
反序列化器以及校验方法
from rest_framework import serializers from students import models # 字段验证函数[只能用于验证一个字段数据] def check_class_num(data): if data == "88888": print(data) raise serializers.ValidationError("一边去,小庙容不下您") return data class StudentSerializers(serializers.Serializer): name = serializers.CharField(max_length=20, required=True) age = serializers.IntegerField(max_value=120, required=True) sex = serializers.BooleanField(default=1) class_num = serializers.CharField(required=True, validators=[check_class_num]) description = serializers.CharField(allow_null=True, allow_blank=True) # 字段验证方法 # validate_字段名() # 验证单个字段 # validate() # 验证所有字段 def validate_name(self, attr): exists = models.Student.objects.filter(name=attr).exists() if exists: raise serializers.ValidationError("姓名不能重复") # 注意,每次验证完成以后必须有结果返回!否则数据就会丢失 return attr def validate(self, attrs): if attrs.get("name") == "乾隆" and attrs.get("sex") == True: raise serializers.ValidationError("别闹") return attrs # 数据校验成功后进行保存 def create(self, validated_data): ret = models.Student.objects.create(**validated_data) return ret # 更新数据 def update(self, instance, validated_data): # instance.name = validated_data.get("name") # instance.age = validated_data.get("age") # instance.sex = validated_data.get("sex") # instance.class_num = validated_data.get("class_num") # instance.description = validated_data.get("description") # 简便写法 for key, value in validated_data.items(): setattr(instance, key, value)
instance.save()
return instance
视图
import json from django.views import View from .serializers import StudentSerializers from django.http.response import HttpResponse, JsonResponse from students import models class StudentView(View): # 提交数据 def post(self, request): data = json.loads(request.body) # print(data) # {'name': 'bob', 'sex': True, 'age': 13, 'class_num': '303', 'description': '张三怕李四'} serializer = StudentSerializers(data=data) ret = serializer.is_valid(raise_exception=True) # print(serializer.validated_data) # OrderedDict([('name', 'bob'), ('age', 13), ('sex', True), ('class_num', '303'), ('description', '张三怕李四')]) # print(serializer.errors) serializer.save() return HttpResponse("ok") # 更新 def put(self, request): # 接收客户端提交的修改数据并获取要更新字段的模型对象 data = json.loads(request.body) pk = data.get("id") obj = models.Student.objects.filter(pk=pk).first() # partial=True表示设置值验证客户端上传来的部分数据,没有上传的字段,即便有选项或者验证方法,也忽略不管. serializer = StudentSerializers(instance=obj, data=data, partial=True) serializer.is_valid(raise_exception=True) """ serializer.save()之所以会自动判断什么时候执行create或者update, 原因是save内部中根据实例化序列化器时是否传递模型对象参数(instance)进来而判断的. """ serializer.save() return HttpResponse("更新成功") # 获取数据 def get(self, request): obj = models.Student.objects.filter(pk=1).first() serializer = StudentSerializers(instance=obj) return JsonResponse(serializer.data, json_dumps_params={"ensure_ascii": False})
3. 模型类序列化器
ModelSerializer与常规的Serializer类似,但提供了以下功能:
-
基于模型类自动生成一系列序列化器字段
-
基于模型类自动为Serializer生成validators,比如unique_together
-
包含默认的create()和update()的实现
子应用中的路由
from django.urls import path, re_path from . import views urlpatterns = [ path("student/", views.StudentView.as_view()), path("student2/", views.Student2View.as_view()) ]
模型类序列化器
# 模型类序列化 class StudentModelSerializers(serializers.ModelSerializer): # 字段声明 token = serializers.CharField(max_length=128, read_only=True, default="123") # 序列化器中也可以转换自定义的字段 # 模型声明 class Meta: model = models.Student fields = ["id","name","age","sex", "token"] # fields = "__all__" # 调用模型所有字段 read_only_fields = ["id"] # read_only_fields 表示设置模型中那些字段属于只读类型的,对于不在模型中字段无效 # 我们可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数 extra_kwargs = { "token": {"read_only": True}, "age": {"min_value": 0, "max_value": 120} }
视图
class Student2View(View): def get(self, request): obj = models.Student.objects.filter(pk=1).first() serializer = StudentModelSerializers(instance=obj) return JsonResponse(serializer.data, json_dumps_params={"ensure_ascii": False}) def post(self, request): data = json.loads(request.body) serializer = StudentModelSerializers(data=data) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data, json_dumps_params={"ensure_ascii": False})
...
4. 请求和响应
4.1 request:
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。[在drf中,原生的django的http请求对象,通过request._request
]
REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中。
Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。
无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。
data属性:
request.data 返回解析之后的<mark>请求体</mark>数据。类似于Django中标准的`request.POST`和 `request.FILES`属性,但提供如下特性: - 包含了解析之后的文件和非文件数据 - 包含了对POST、PUT、PATCH请求方式解析后的数据 - 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据 相当于drf的request.data替代了 django的request.POST,request.FILES,request.body、
query_params属性
request.query_params返回解析之后的<mark>查询字符串</mark>数据
request.query_params与Django原生的request.GET相同,只是更换了更正确的名称而已。
4.2 Reponse:
rest_framework.response.Response
REST framework提供了一个响应类Response
,使用该类构造响应对象时,响应的具体数据内容会被转换(renderer渲染器)成符合前端需求的类型。
REST framework提供了Renderer
渲染器,用来根据请求头中的Accept
可以在rest_framework.settings.py查找所有的drf默认配置项
参数说明: - `data`: 为响应准备的序列化处理后的数据; - `status`: 状态码,默认200;
- `template_name`: 模板名称,如果使用`HTMLRenderer` 时需指明; - `headers`: 用于存放响应头信息的字典; - `content_type`: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。
5. REST framework 中提供的视图
子应用中的urls.py
from django.urls import path, re_path from . import views urlpatterns = [ path("student/", views.StudentAPIView.as_view()), re_path("^student2/(?P<pk>\d+)/$", views.Student2APIView.as_view()) ]
serializers.py
from rest_framework import serializers from students import models class StudnetModelSerializers(serializers.ModelSerializer): class Meta: model = models.Student fields = "__all__" class Studnet2ModelSerializers(serializers.ModelSerializer): class Meta: model = models.Student fields = ["id", "name"]
views.py
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from students import models from .serializers import StudnetModelSerializers class StudentAPIView(APIView): def get(self, request): obj_list = models.Student.objects.all() serializer = StudnetModelSerializers(instance=obj_list, many=True) return Response(serializer.data) def post(self, request): data = request.data # 直接用request.data接收数据 serializer = StudnetModelSerializers(data=data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) class Student2APIView(APIView): def put(self, request, pk): obj = models.Student.objects.filter(pk=pk).first() data = request.data serializer = StudnetModelSerializers(instance=obj, data=data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def get(self, request, pk): print(111) obj = models.Student.objects.filter(pk=pk).first() serializer = StudnetModelSerializers(instance=obj) return Response(serializer.data) def delete(self, request, pk): models.Student.objects.filter(pk=pk).delete() return Response("删除成功", status=status.HTTP_200_OK)
6.
属性: serializer_class 指明视图使用的序列化器 queryset 指明使用的数据查询集 方法: get_serializer_class(self): 当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了。 返回序列化器类,默认返回`serializer_class`,可以进行改写 get_serializer(self, *args, \**kwargs): 返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法。 注意,该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。 - request 当前视图的请求对象 - view 当前请求的类视图对象 - format 当前请求期望返回的数据格式 get_queryset(self): 返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以进行改写 get_object(self): 返回单个视图模型类对象,主要用来提供给Mixin扩展类使用。 在试图中可以调用该方法获取详情信息的模型类对象。 若详情访问的模型类对象不存在,会返回404。 该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
urls.py
from django.urls import path, re_path from . import views urlpatterns = [ path("student/", views.StudentGenericAPIView.as_view()), re_path("^student2/(?P<pk>\d+)/$", views.Student2GenericAPIView.as_view()), path("student3/", views.Student3APIView.as_view()), re_path("^student4/(?P<pk>\d+)/$", views.Student4APIView.as_view()), ]
serializers.py:
from rest_framework import serializers from students import models class StudnetModelSerializers(serializers.ModelSerializer): class Meta: model = models.Student fields = "__all__" class Studnet2ModelSerializers(serializers.ModelSerializer): class Meta: model = models.Student fields = ["id", "name"]
views.py
from rest_framework.generics import GenericAPIView from rest_framework.response import Response from rest_framework import status from demo.serializers import StudnetModelSerializers, Studnet2ModelSerializers from students import models class StudentGenericAPIView(GenericAPIView): queryset = models.Student.objects def get_serializer_class(self): if self.request.method.lower() == "get": return Studnet2ModelSerializers else: return StudnetModelSerializers def get(self, request): serializer = self.get_serializer(instance=self.get_queryset(), many=True) return Response(serializer.data) def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) class Student2GenericAPIView(GenericAPIView): serializer_class = StudnetModelSerializers queryset = models.Student.objects def put(self, request, pk): data = request.data # serializer = self.serializer_class(instance=self.queryset.filter(pk=pk).first(), data=data) serializer = self.get_serializer(instance=self.get_object(), data=data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def get(self, request, pk): # serializer = self.serializer_class(instance=self.queryset.filter(pk=pk).first()) serializer = self.get_serializer(instance=self.get_object()) return Response(serializer.data) def delete(self, request, pk): self.queryset.filter(pk=pk).delete() return Response("删除成功",status=status.HTTP_200_OK)