前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Sentry 开发者贡献指南 - Django Rest Framework(Serializers)

Sentry 开发者贡献指南 - Django Rest Framework(Serializers)

作者头像
为少
发布2022-01-25 08:39:47
1.1K0
发布2022-01-25 08:39:47
举报
文章被收录于专栏:黑客下午茶

内容整理自官方开发文档

目录

  • Django Rest Framework
  • 示例
  • 用法
  • Model Serializer
  • 更多

Serializer 用于获取复杂的 python 模型并将它们转换为 json。序列化程序还可用于在验证传入数据后将 json 反序列化回 Python 模型。

Sentry,我们有两种不同类型的序列化器 :Django Rest Framework SerializerModel Serializer

Django Rest Framework

Django Rest Framework 序列化程序用于处理进入 Sentry 的数据的输入验证和转换。

  • https://www.django-rest-framework.org/

示例

在典型的 serializer 中,指定了字段,以便它们根据您的规范验证数据的类型和格式。如果写入适合 modelDjango Rest Framework 序列化程序还可以将信息保存到数据库中。

代码语言:javascript
复制
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 将接受并验证包含三个字段的 jsonnameagetype。其中 nametype 必须是stringsage 必须是建议的 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 的典型用法

代码语言:javascript
复制
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 FrameworkSerializer 将用于需要验证的传入数据的方法(即 putpost 方法)。一旦序列化器被实例化,你可以调用 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

代码语言:javascript
复制
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
代码语言:javascript
复制
@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 是必需的,以便

代码语言:javascript
复制
`return Response(serialize(example, request.user), status=201)`

works. 在这种情况下,它会在后台搜索匹配的模型 Example, 给定变量 examplemodel 类型。要将 model serializerModel 匹配,您只需执行

代码语言:javascript
复制
@register(<ModelName>)
class ModelSerializer(Serializer):
...

get_attrs 方法

Django Rest Framework 具有类似功能时,为什么要这样做? get_attrs 方法就是原因。它允许您执行批量查询而不是多个查询。在我们的示例中,我可以过滤我想要的 item,并使用 python 将它们分配给相关 item, 而不是调用 ExampleTypes.objects.get(...) 多个 item。在 attr 字典的情况下,keyitem 本身。并且 value 是一个字典,其中包含要添加的属性的名称及其值。

代码语言:javascript
复制
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 部署与故障排除详解

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑客下午茶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • Django Rest Framework
    • 示例
      • 用法
      • Model Serializer
      • 更多
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档