内容整理自官方开发文档
目录
- Django Rest Framework
- 示例
- 用法
- Model Serializer
- 更多
Serializer
用于获取复杂的 python
模型并将它们转换为 json
。序列化程序还可用于在验证传入数据后将 json
反序列化回 Python
模型。
在 Sentry
,我们有两种不同类型的序列化器 :Django Rest Framework Serializer
和 Model Serializer
。
Django Rest Framework
Django Rest Framework
序列化程序用于处理进入 Sentry
的数据的输入验证和转换。
- https://www.django-rest-framework.org/
示例
在典型的 serializer
中,指定了字段,以便它们根据您的规范验证数据的类型和格式。如果写入适合 model
,Django Rest Framework
序列化程序还可以将信息保存到数据库中。
from rest_framework import serializers
from sentry.api.serializers.rest_framework import ValidationError
class ExampleSerializer(serializers.Serializer):
name = serializers.CharField()
age = serializers.IntegerField(required=False)
type = serializers.CharField()
def validate_type(self, attrs, source):
type = attrs[source]
if type not in ['bear', 'rabbit', 'puppy']:
raise ValidationError('%s is not a valid type' % type)
return attrs
字段检查
在上面的示例中, serializer
将接受并验证包含三个字段的 json
:name
、age
和 type
。其中 name
和 type
必须是strings
, age
必须是建议的 integer
。默认情况下,字段是必需的,如果不提供,serializer
将标记为无效。请注意,integer
字段 age
,required
设置为 False
。因此可能不包括在内,serializer
仍将被视为有效。
自定义验证
对于需要自定义验证的值(除了简单的类型检查),
def validate_<variable_name>(self, attrs, source)
可以创建其中 <variable_name>
替换为给定字段的确切变量名称。因此,例如,如果我有一个字段名称 typeName
,验证方法名称将是 validate_typeName
, 而如果我有一个名为 type_name
的字段,验证方法名称将是 validate_type_name
。在上面给出的示例中,类型被检查并且必须是某个字符串。如果某个字段与您的验证方法所期望的不匹配,则会引发 ValidationError
。
用法
在 endpoint
中,这是 Django Rest Framework Serializer
的典型用法
class ExampleEndpoint(Endpoint):
def post(self, request):
serializer = ExampleSerializer(request.DATA)
if not serializer.is_valid():
return Response(serializer.errors, status=400)
result = serializer.object
#Assuming Example is a model with the same fields
try:
with transaction.atomic():
Example.objects.create(
name=result['name'],
age=result.get('age'),
type=result['type'],
)
except IntegrityError:
return Response('This example already exists', status=409)
return Response(serialize(result, request.user), status=201)
验证数据
来自 Django Rest Framework
的 Serializer
将用于需要验证的传入数据的方法(即 put
和 post
方法)。一旦序列化器被实例化,你可以调用 serializer.is_valid()
来验证数据。 serializer.errors
将给出关于给定数据无效的具体反馈。
例如给定的输入
代码语言:javascript复制{
'age':5,
'type':'puppy'
}
serializer
将返回一个错误,指出未提供所需的字段名称。
保存数据
确认数据有效后,您可以通过以下两种方式之一保存数据。上面给出的例子是 sentry
中最常见的。取 serializer.object
,它只是经过验证的数据(如果 serializer.is_valid()
返回 False
,则为 None
) 并使用 <ModelName>.objects.create
将该数据直接保存在 model
中.
另一种方法使用了更多的 Django Rest Framework
的特性, ModelSerializer
from rest_framework import serializers
from sentry.api.serializers.rest_framework import ValidationError
class ExampleSerializer(serializer.ModelSerializer):
name = serializers.CharField()
age = serializers.IntegerField(required=False)
type = serializers.CharField()
class Meta:
model = Example
def validate_type(self, attrs, source):
type = attrs[source]
if type not in ['bear', 'rabbit', 'puppy']:
raise ValidationError('%s is not a valid type' % type)
return attrs
class ExampleEndpoint(Endpoint):
def post(self, request):
serializer = ExampleSerializer(request.DATA)
if not serializer.is_valid():
return Response(serializer.errors, status=400)
example = serializer.save()
return Response(serialize(example, request.user), status=201)
Model Serializer
Sentry's Model Serializers 仅用于传出数据。典型的 model serializer
如下所示:
- https://github.com/getsentry/sentry/blob/master/src/sentry/api/serializers/base.py
@register(Example)
class ExampleSerializer(Serializer):
def get_attrs(self, item_list, user):
attrs = {}
types = ExampleTypes.objects.filter(
type_name__in=[i.type for i in item_list]
)
for item in item_list:
attrs[item] = {}
attrs[item]['type'] = [t for t in types if t.name == item.type_name]
return attrs
def serialize(self, obj, attrs, user):
return {
'name':obj.name,
'type':attrs['type'],
'age': obj.age,
}
注册 Model Serializer
装饰器 @register
是必需的,以便
`return Response(serialize(example, request.user), status=201)`
works. 在这种情况下,它会在后台搜索匹配的模型 Example
, 给定变量 example
的 model
类型。要将 model serializer
与 Model
匹配,您只需执行
@register(<ModelName>)
class ModelSerializer(Serializer):
...
get_attrs 方法
当 Django Rest Framework
具有类似功能时,为什么要这样做? get_attrs
方法就是原因。它允许您执行批量查询而不是多个查询。在我们的示例中,我可以过滤我想要的 item
,并使用 python
将它们分配给相关 item
, 而不是调用 ExampleTypes.objects.get(...)
多个 item
。在 attr
字典的情况下,key
是 item
本身。并且 value
是一个字典,其中包含要添加的属性的名称及其值。
attrs[item] = {'attribute_name': attribute}
Serialize 方法
最后,您返回一个带有 json
可序列化信息的字典,该信息将与 response
一起返回。
更多
Sentry 企业级数据安全解决方案 - Relay PII 和数据清理
Sentry 企业级数据安全解决方案 - Relay 入门
Sentry 企业级数据安全解决方案 - Relay 运行模式
Sentry 企业级数据安全解决方案 - Relay 配置选项
Sentry 企业级数据安全解决方案 - Relay 监控 & 指标收集
Sentry 企业级数据安全解决方案 - Relay 项目配置
Sentry 企业级数据安全解决方案 - Relay 操作指南
Sentry 开源版与商业 SaaS 版的区别
Sentry 开发者贡献指南 - Feature Flag
Sentry 开发者贡献指南 - 前端(ReactJS生态)
Sentry 监控 - 私有 Docker Compose 部署与故障排除详解