drf Serializer使用
drf序列化
在前后端不分离的项目中,可以使用Django
自带的forms
组件进行数据验证,也可以使用Django
自带的序列化组件对模型表数据进行序列化。
那么在前后端分离的项目中,drf
也提供了数据验证与序列化,相比于Django
原生的序列化它更加强大与易用。
准备工作
注册drf
首先第一步,我们需要在项目全局文件夹中注册drf
INSTALLED_APPS = [
'app01.apps.App01Config',
'rest_framework', # 注册drf
]
模型表
下面是项目中的模型表。
学生和班级是一对多
班级和老师是多对多
班级和班主任是一对一
from django.db import models
# Create your models here.
class Student(models.Model):
student_id = models.AutoField(primary_key=True, verbose_name="学生编号")
student_name = models.CharField(max_length=8, verbose_name="学生姓名")
student_gender = models.BooleanField(
choices=([0, "male"], [1, "female"]), default=0, verbose_name="学生性别")
student_class = models.ForeignKey(
to="Classes", verbose_name="所属班级", on_delete=models.CASCADE) # 一个班级多个学生
def __str__(self):
return self.student_name
class Meta:
db_table = ''
managed = True
verbose_name = 'Student'
verbose_name_plural = 'Students'
class Classes(models.Model):
class_id = models.AutoField(primary_key=True, verbose_name="班级编号")
class_name = models.CharField(max_length=8, verbose_name="班级名称")
class_teacher = models.OneToOneField(
to="Teacher", verbose_name="班主任", on_delete=models.CASCADE) # 一个班级只有一个班主任
def __str__(self):
return self.class_name
class Meta:
db_table = ''
managed = True
verbose_name = 'Classes'
verbose_name_plural = 'Classess'
class Teacher(models.Model):
teacher_id = models.AutoField(primary_key=True, verbose_name="教师编号")
teacher_name = models.CharField(max_length=8, verbose_name="教师姓名")
teacher_class = models.ManyToManyField(
to="Classes", verbose_name="任教班级") # 一个班级中可有多个老师,一个老师也可以在多个班级中任教
def __str__(self):
return self.teacher_name
class Meta:
db_table = ''
managed = True
verbose_name = 'Teacher'
verbose_name_plural = 'Teachers'
数据展示
学生信息如下:
mysql> select * from app01_student;
+------------+--------------+----------------+------------------+
| student_id | student_name | student_gender | student_class_id |
+------------+--------------+----------------+------------------+
| 1 | 学生1 | 1 | 1 |
| 2 | 学生2 | 1 | 2 |
| 3 | 学生3 | 1 | 2 |
| 4 | 学生4 | 0 | 1 |
+------------+--------------+----------------+------------------+
教师信息如下:
mysql> select * from app01_teacher;
+------------+--------------+
| teacher_id | teacher_name |
+------------+--------------+
| 1 | 王老师 |
| 2 | 李老师 |
| 3 | 张老师 |
+------------+--------------+
班级信息如下:
mysql> select * from app01_classes;
+----------+--------------+------------------+
| class_id | class_name | class_teacher_id |
+----------+--------------+------------------+
| 1 | 高一一班 | 1 |
| 2 | 高二一班 | 2 |
+----------+--------------+------------------+
教师与班级关系如下:
mysql> select * from app01_teacher_teacher_class;
+----+------------+------------+
| id | teacher_id | classes_id |
+----+------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 1 |
| 6 | 3 | 2 |
+----+------------+------------+
url书写
接下来书写url
,以查询学生模型表为例,为了符合result
规范,所以要有一个有名分组来接收可能获取/修改/删除的编号。
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/students/(?P<sid>\d+)?', views.Student.as_view()),
]
# 添加问号,代表可有,可没有
自定义序列器
使用自定义序列器。可以更加灵活的使用序列化及反序列化。也是推荐使用的方式。
创建序列类
序列类的作用如下:
- 序列化时,可选择序列化的模型表字段
- 反序列化时,可选择对数据验证的规则,类似于forms组件
from .models import Student
from rest_framework import serializers
class StudentSerializer(serializers.Serializer):
student_id = serializers.CharField()
student_name = serializers.CharField()
student_gender = serializers.BooleanField()
student_class = serializers.CharField()
进行序列化
接下来进行序列化,首先要书写视图函数。
由于我们每次都需要返回一个状态码,以及内容包装,所以可以创建一个构建返回内容的类。
第一步要将序列化类导入,在进行序列化的时候将需要序列化的数据对象进行传入。
当序列化完成后,得到一个序列化对象,它有一个data
属性,是已经序列化完成的一个字典。
把字典返回,如果不使用rest_framework
提供的Response
,就得使用JsonResponse
。
序列化单个对象,不需要在序列化时指定参数many
序列化多个对象,需要在序列化时指定参数many
from rest_framework.views import APIView
from rest_framework.views import Request
from rest_framework.views import Response # 通过Response返回
from app01 import models
from app01.drf_ser import StudentSerializer
class returnData(object):
# 构建返回的信息
def __init__(self):
self.status = 100 # 100代表成功,200代表失败
self.message = None # 返回的信息
self.data = None # 序列化后的结果
def get_dict(self):
return self.__dict__
@property
def data(self):
return self.data
@data.setter
def data(self, value):
self.__dict__["data"] = value
class Student(APIView):
def get(self, request, sid=None):
# 初始化返回信息
res = returnData()
if sid:
# 代表获取单个
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentSerializer(obj)
res.data = serializer_result.data
else:
res.message = "没有该学生"
res.status = 200
return Response(res.get_dict())
else:
# 代表获取所有
obj_queryset = models.Student.objects.all()
if obj_queryset:
serializer_result = StudentSerializer(
obj_queryset, many=True) # many=True代表获取多条
res.data = serializer_result.data
else:
res.message = "暂时没有任何学生"
res.status = 200
return Response(res.get_dict())
def post(self, request, sid):
# 新增
pass
def delete(self, request, sid):
# 删除
pass
def patch(self, request, sid):
# 修改
pass
序列化时,只关心怎样将数据返回给页面。
所以我们只做GET
部分,注意用if
判断来判定是获取所有,还是获取单个。
以下是获取全部的结果:
# http://127.0.0.1:8000/api/students/
{
"status": 100,
"message": null,
"data": [
{
"student_id": "1",
"student_name": "学生1",
"student_gender": true,
"student_class": "高一一班"
},
{
"student_id": "2",
"student_name": "学生2",
"student_gender": true,
"student_class": "高二一班"
},
{
"student_id": "3",
"student_name": "学生3",
"student_gender": true,
"student_class": "高二一班"
},
{
"student_id": "4",
"student_name": "学生4",
"student_gender": false,
"student_class": "高一一班"
}
]
}
以下是获取单条的结果:
{
"status": 100,
"message": null,
"data": {
"student_id": "1",
"student_name": "学生1",
"student_gender": true,
"student_class": "高一一班"
}
}
当获取出错时,message
中就会存在错误信息:
{
"status": 200,
"message": "没有该学生",
"data": null
}
反序列化参数介绍
反序列化通常是使用POST/PATCH
插入或更新数据时使用,收集到页面传递的数据,进行反序列化后写入数据库中。
当进行反序列化时,可以在序列类中指定一些参数,对将要反序列化写入模型表的字段进行检查。
参数 | 描述 |
---|---|
max_length | 最大长度 |
min_lenght | 最小长度 |
allow_blank | 是否允许为空 |
trim_whitespace | 是否截断空白字符 |
max_value | 最小值 |
min_value | 最大值 |
required | 表明该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
allow_null | 表明该字段是否允许传入None,默认False |
validators | 该字段使用的验证器 |
error_messages | 包含错误编号与错误信息的字典 |
初此之外,还有两个比较特殊的参数:
参数 | 描述 |
---|---|
read_only | 表明该字段仅用于序列化输出,默认False,如果设置成True,postman中可以看到该字段,修改时,不需要传该字段 |
write_only | 表明该字段仅用于反序列化输入,默认False,如果设置成True,postman中看不到该字段,修改时,该字段需要传 |
反序列化钩子
validate_字段名
是局部钩子
validate
是全局钩子
如果要在钩子中抛出异常,则需要导入异常模块。
from rest_framework import exceptions
# raise exceptions.ValidationError('异常了')
如下是局部钩子的使用示例,因为页面提交过来的数据关于一对多中的班级字段是字符串,所以我们需要将字符串变为模型表对象,方便后面的创建以及更新。
def validate_student_class(self, data):
# data是提交过来的这一个字段的数据
class_obj = Classes.objects.filter(class_name=data).first()
if not class_obj:
raise exceptions.ValidationError("班级不存在")
data = class_obj # 将字符串替换为对象
return data
全局钩子使用也是一样。如下,验证学生名和班级名是否相同,如果相同则抛出异常
def validate(self, validate_data):
student_name = validate_data.get("student_name")
class_obj = validate_data.get("student_class") # 由于局部钩子中,这里被替换成了对象,所以我们拿到对象不能直接作比较
if student_name == class_obj.class_name:
raise exceptions.ValidationError("学生名不能和班级名相同")
return validate_data
create&update
在进行反序列化时,必须在序列类中覆写create()
方法以及update()
方法。
其中create()
方法针对的是新增用户,而update()
方法针对的是更新用户。
如果不进行覆写,则会抛出异常,这是因为作者在源码中做了接口约束的设置:
def update(self, instance, validated_data):
raise NotImplementedError('`update()` must be implemented.')
def create(self, validated_data):
raise NotImplementedError('`create()` must be implemented.')
反序列化案例
了解了上面反序列化需要注意的事项后,开始书写视图函数中的POST/PATCH
方法。
下面是创建一个学生的例子:
def post(self, request):
# 初始化返回信息
res = returnData()
serializer_result = StudentSerializer(data=request.data) # 传入request.data即可。这里一定要使用关键字传参!!!
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回新增的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
return Response(res.get_dict())
重写create()
方法并返回:
def create(self, validated_data):
instance = Student.objects.create(**validated_data)
return instance # 这里返回的信息会返回到序列类对象的data属性中
下面是修改一个学生的例子:
def patch(self, request, sid):
# 初始化返回信息
res = returnData()
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentSerializer(instance=obj, data=request.data) # 需要传入的参数,记录本身,新的数据
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回修改的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
else:
res.status = 200
res.message = "用户不存在"
return Response(res.get_dict())
重写update()
方法并返回:
def update(self, instance, validated_data):
# 对数据做更新后再返回
# validated_data中取出str的键,然后用反射进行设置
for k, v in validated_data.items():
setattr(instance, k, v)
instance.save()
return instance
全部代码
views.py
from rest_framework.views import APIView
from rest_framework.views import Request
from rest_framework.views import Response # 通过Response返回
from app01 import models
from app01.drf_ser import StudentSerializer # 导入自定义序列类
class returnData(object):
# 构建返回的信息
def __init__(self):
self.status = 100 # 100代表成功,200代表失败
self.message = None # 返回的信息
self.data = None # 序列化后的结果
def get_dict(self):
return self.__dict__
@property
def data(self):
return self.data
@data.setter
def data(self, value):
self.__dict__["data"] = value
class Student(APIView):
def get(self, request, sid=None):
# 初始化返回信息
res = returnData()
if sid:
# 代表获取单个
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentSerializer(obj)
res.data = serializer_result.data
else:
res.message = "没有该学生"
res.status = 200
return Response(res.get_dict())
else:
# 代表获取所有
obj_queryset = models.Student.objects.all()
if obj_queryset:
serializer_result = StudentSerializer(
obj_queryset, many=True) # many=True代表获取多条
res.data = serializer_result.data
else:
res.message = "暂时没有任何学生"
res.status = 200
return Response(res.get_dict())
def post(self, request):
# 初始化返回信息
res = returnData()
serializer_result = StudentSerializer(
data=request.data) # 传入request.data即可
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回新增的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
return Response(res.get_dict())
def delete(self, request):
# 删除
pass
def patch(self, request, sid):
# 初始化返回信息
res = returnData()
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentSerializer(instance=obj, data=request.data) # 需要传入的参数,记录本身,新的数据
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回修改的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
else:
res.status = 200
res.message = "用户不存在"
return Response(res.get_dict())
自定义序列类
from .models import Student
from .models import Classes
from rest_framework import serializers
from rest_framework import exceptions
class StudentSerializer(serializers.Serializer):
student_id = serializers.CharField(read_only=True) # 创建/修改时不用传该字段,但是页面可以看见
# 相反的,如果是wrtie_only则代表页面看不见,但是你要传
student_name = serializers.CharField(max_length=8, min_length=3)
student_gender = serializers.BooleanField()
student_class = serializers.CharField()
def validate_student_class(self, data):
class_obj = Classes.objects.filter(class_name=data).first()
if not class_obj:
raise exceptions.ValidationError("班级不存在")
data = class_obj # 将字符串替换为对象
return data
def validate(self, validate_data):
student_name = validate_data.get("student_name")
class_obj = validate_data.get("student_class")
if student_name == class_obj.class_name:
raise exceptions.ValidationError("学生名不能和班级名相同")
return validate_data
def create(self, validated_data):
instance = Student.objects.create(**validated_data)
return instance # 这里返回的信息会返回到序列类对象的data属性中
def update(self, instance, validated_data):
# 对数据做更新后再返回
# validated_data中取出str的键,然后用反射进行设置
for k, v in validated_data.items():
setattr(instance, k, v)
instance.save()
return instance
模型表序列器
模型表的序列器定制化比较低,但是使用较为方便。
能够非常快速的开发接口。
创建序列类
创建序列器:
# 模型表序列器
class StudentModelSerializer(serializers.ModelSerializer):
student_id = serializers.CharField(read_only=True) # 创建/修改时不用传该字段,但是页面可以看见
student_name = serializers.CharField(max_length=8, min_length=3)
student_gender = serializers.BooleanField()
student_class = serializers.CharField()
class Meta:
model = Student # 对应上models.py中的模型
fields = '__all__' # 序列化所有字段
# fields=('student_id','student_name') # 只序列化指定的字段
# exclude=('student_id',) # 跟fields不能同时都写,写谁,就表示排除谁
# read_only_fields=('student_id',)
# write_only_fields=('student_class',) # 弃用了,使用extra_kwargs
# extra_kwargs = { # 类似于这种形式 student_name=serializers.CharField(max_length=16,min_length=4)
# 'student_name': {'write_only': True},
# }
def validate_student_class(self, data):
class_obj = Classes.objects.filter(class_name=data).first()
if not class_obj:
raise exceptions.ValidationError("班级不存在")
data = class_obj # 将字符串替换为对象
return data
def validate(self, validate_data):
student_name = validate_data.get("student_name")
class_obj = validate_data.get("student_class")
print(class_obj)
if student_name == class_obj.class_name:
raise exceptions.ValidationError("学生名不能和班级名相同")
return validate_data
基本使用
其他使用一模一样,注意在反序列化时不需要重写create()
和updata()
方法了。
以下是视图API
接口中的代码,只需要把原本使用自定义序列器的地方修改成使用模型表序列器即可。
from rest_framework.views import APIView
from rest_framework.views import Request
from rest_framework.views import Response # 通过Response返回
from app01 import models
# from app01.drf_ser import StudentModelSerializer
from app01.drf_ser import StudentModelSerializer
class returnData(object):
# 构建返回的信息
def __init__(self):
self.status = 100 # 100代表成功,200代表失败
self.message = None # 返回的信息
self.data = None # 序列化后的结果
def get_dict(self):
return self.__dict__
@property
def data(self):
return self.data
@data.setter
def data(self, value):
self.__dict__["data"] = value
class Student(APIView):
def get(self, request, sid=None):
# 初始化返回信息
res = returnData()
if sid:
# 代表获取单个
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentModelSerializer(obj)
res.data = serializer_result.data
else:
res.message = "没有该学生"
res.status = 200
return Response(res.get_dict())
else:
# 代表获取所有
obj_queryset = models.Student.objects.all()
if obj_queryset:
serializer_result = StudentModelSerializer(
obj_queryset, many=True) # many=True代表获取多条
res.data = serializer_result.data
else:
res.message = "暂时没有任何学生"
res.status = 200
return Response(res.get_dict())
def post(self, request):
# 初始化返回信息
res = returnData()
serializer_result = StudentModelSerializer(
data=request.data) # 传入request.data即可
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回新增的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
return Response(res.get_dict())
def delete(self, request):
# 删除
pass
def patch(self, request, sid):
# 初始化返回信息
res = returnData()
obj = models.Student.objects.filter(pk=sid).first()
if obj:
serializer_result = StudentModelSerializer(instance=obj, data=request.data) # 需要传入的参数,记录本身,新的数据
if serializer_result.is_valid():
# 验证通过了
serializer_result.save() # 保存序列化实例类
res.data = serializer_result.data # 遵循规范,返回修改的数据
else:
# 验证没通过
res.status = 200
res.message = "数据校验失败"
res.data = serializer_result.errors # 添加错误信息
else:
res.status = 200
res.message = "用户不存在"
return Response(res.get_dict())
多关系子序列化
source参数
source
参数的使用:
- 可以改字段名字 xxxx=serializers.CharField(source='student_name')
- 可以
.
跨表 cls=serializers.CharField(source='student_class.name') # 相当于 student_student_class__name进行数据获取 - 可以执行方法pub_date=serializers.CharField(source='test') test是Student表模型中的方法(可忽略,这个相当于验证方法。还不如使用钩子函数)
该参数最重要的两点,source
中写的是什么,就从哪里取数据,即展示的就是什么。当反序列化时,不再按照序列器类的字段名进行反序列化,而是按照该参数进行反序列化填值。
看一下,我要让student_name
显示的不是学生的名字,而是班主任的名字,就用到了第一条和第二条,跨表,显示数据,可以这样设置。
class StudentSerializer(serializers.Serializer):
student_id = serializers.CharField(read_only=True) # 创建/修改时不用传该字段,但是页面可以看见
student_name = serializers.CharField(max_length=8, min_length=3,source="student_class.class_teacher.teacher_name") # 相当于:Student.objects.filter(pk=传入的id).values_list("student_class__class_teacher__teacher_name")[0][0]
student_gender = serializers.BooleanField(source="student_gender")
student_class = serializers.CharField()
当进行GET
请求后,将会看到下面的结果:
# http://127.0.0.1:8000/api/students/5/
{
"status": 100,
"message": null,
"data": {
"student_id": "5",
"student_name": "王老师", # 所以说,该参数后面写的是什么,展示的就是什么。
"student_gender": false,
"student_class": "高一一班"
}
}
示例演示,我们通常会将展示的数据名字进行重命名,区分开与数据库存储的字段名,这样做更加安全,所以可以进行如下设置:
from .models import Student
from .models import Classes
from rest_framework import serializers
from rest_framework import exceptions
class StudentSerializer(serializers.Serializer):
sid = serializers.CharField(read_only=True,source="student_id") # 创建/修改时不用传该字段,但是页面可以看见
name = serializers.CharField(max_length=8, min_length=3,source="student_name")
gender = serializers.BooleanField(source="student_gender")
classes = serializers.CharField(source="student_class") # source中写的是什么,就从哪里取数据
def validate_classes(self, data):
# data是提交过来的这一个字段的数据
class_obj = Classes.objects.filter(class_name=data).first()
if not class_obj:
raise exceptions.ValidationError("班级不存在")
data = class_obj # 将字符串替换为对象
return data
def create(self, validated_data):
instance = Student.objects.create(**validated_data)
return instance # 这里返回的信息会返回到序列类对象的data属性中
def update(self, instance, validated_data):
# 对数据做更新后再返回
# validated_data中取出str的键,然后用反射进行设置
for k, v in validated_data.items():
setattr(instance, k, v)
instance.save()
return instance
{
"status": 100,
"message": null,
"data": {
"sid": "5",
"name": "修改学生5",
"gender": false,
"classes": "高一一班"
}
}
SerializerMethodField字段
它需要有个配套方法,方法名叫get_字段名
,返回值就是要显示的东西。
比如,我们想查看每个学生都有那些老师在教授,就可以使用该参数:
class StudentSerializer(serializers.Serializer):
sid = serializers.CharField(read_only=True,source="student_id") # 创建/修改时不用传该字段,但是页面可以看见
name = serializers.CharField(max_length=8, min_length=3,source="student_name")
gender = serializers.BooleanField(source="student_gender")
classes = serializers.CharField(source="student_class") # 现在,我要让他显示的是班级编号,而不再是班级名称了
students = serializers.SerializerMethodField()
def get_students(self,instance):
teacher_queryset = instance.student_class.teacher_set.values("pk","teacher_name")
return teacher_queryset
最后的结果如下:
# http://127.0.0.1:8000/api/students/5/
{
"status": 100,
"message": null,
"data": {
"sid": "5",
"name": "修改学生5",
"gender": false,
"classes": "高一一班",
"students": [
{
"pk": 1,
"teacher_name": "王老师"
},
{
"pk": 2,
"teacher_name": "李老师"
},
{
"pk": 3,
"teacher_name": "张老师"
}
]
}
}
drf Serializer使用的更多相关文章
- django restframework Serializer field
SerializerMethodField 这是一个只读字段.它通过调用它所连接的序列化类的方法来获得它的值.它可用于将任何类型的数据添加到对象的序列化表示中. 签名: SerializerMetho ...
- restful(1):序列化
restful协议中,一切皆是资源,操作只是请求方式 model_to_dict()方法: from django.forms.models import model_to_dict obj = Pu ...
- drf-Serializers
What is serializers? serializers主要作用是将原生的Python数据类型(如 model querysets )转换为web中通用的JSON,XML或其他内容类型. DR ...
- 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...
- Django框架(十八)—— drf:序列化组件(serializer)
序列化组件 # 模型层 from django.db import models class Book(models.Model): nid = models.AutoField(primary_ke ...
- Django框架之DRF APIView Serializer
一.APIView 我们在使用DjangoRestfulFramework的时候会将每个视图类继承APIView,取代原生Django的View类 APIView的流程分析: rest_framewo ...
- DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)
解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...
- drf框架 - 序列化组件 | Serializer
序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 序列化与反序列化 序列化: 将对象序列化成字符串用户传输 ...
- 第三章、drf框架 - 序列化组件 | Serializer
目录 第三章.drf框架 - 序列化组件 | Serializer 序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer( ...
随机推荐
- Redis安装即python使用
一:简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted ...
- 【答疑解惑】为什么你的 Charles 会抓包失败?
作为一名 Web 开发工程师,天天都会和网络打交道.Charles 作为一款网络抓包工具,几乎成了 Web 开发的标配. 本文是我深度使用 Charles 后总结而成,不同于其它介绍 Charles ...
- Redis学习(一)认识并安装redis
一.初识redis Redis是一个开源的Key-Value数据库,通常被称为数据结构服务器,其值可以是多种常见的数据格式,且读写性能极高,且所有操作都是原子性的. Redis是运行在内存中的,但是可 ...
- Salesforce LWC学习(二十六) 简单知识总结篇三
首先本篇感谢长源edward老哥的大力帮助. 背景:我们在前端开发的时候,经常会用到输入框,并且对这个输入框设置 required或者其他的验证,当不满足条件时使用自定义的UI或者使用标准的 inpu ...
- BurpSuite抓取本地包方法
本文重点在介绍抓本地包, 而非介绍抓包步骤 Burpsuite配置 默认配置即可 Chrome 浏览器配置 Falcon Proxy扩展程序配置浏览器代理. 需要抓包的网页是个本地搭建的网址, 一般会 ...
- P 3396 哈希冲突 根号分治
Link 据说这是一道论文题????.具体论文好像是 集训队论文<根号算法--不只是分块> 根号分治的裸题. 首先我们考虑暴力怎么打. 先预处理出每个模数的答案,之后再 O(1) 的回答, ...
- Tomcat 第六篇:类加载机制
1. 引言 Tomcat 在部署 Web 应用的时候,是将应用放在 webapps 文件夹目录下,而 webapps 对应到 Tomcat 中是容器 Host ,里面的文件夹则是对应到 Context ...
- 用vscode写python,from引用本地文件的时候老是有红色波浪线,很不爽
前言 出于一些原因,国际关系等等,最近想把开发工具切换到一些免费开源的工具上面,先尝试了在vscode上搭建python环境,总体还是很简单的, 网上教程很多,vscode本身的插件也很丰富,可惜了国 ...
- Hadoop框架:NameNode工作机制详解
本文源码:GitHub·点这里 || GitEE·点这里 一.存储机制 1.基础描述 NameNode运行时元数据需要存放在内存中,同时在磁盘中备份元数据的fsImage,当元数据有更新或者添加元数据 ...
- 如何让程序像人一样的去批量下载歌曲?Python爬取付费歌曲
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 今天来教大家一个自动化爬虫的工具 selenium selenium Se ...