Django Rest Framework - 如何在序列化器中嵌套多个字段?

2023-11-23

我有几个带有多个控制字段的基本模型。其中位置字段由纬度、经度、精度、提供商和客户时间组合而成。我的大多数可写模型(以及资源​​)都是从这个基本模型继承的。

我试图让 DRF 序列化嵌套“位置”字段中的位置相关字段。例如,

{
 "id": 1, 
 "name": "Some name",
 "location": { 
   "lat": 35.234234, 
   "lon": 35.234234,
   "provider": "network", 
   "accuracy": 9.4, 
 }
}

请务必记住,这些字段是基本模型上的常规(平面)字段。

我调查过并找到了几种选择

  1. 创建自定义字段并通过覆盖“get_attribute”创建嵌套表示。我不喜欢这个解决方案,因为我失去了模型序列化器的一些好处,例如验证。

  2. 创建一个名为 Location 的嵌套资源。我想我可以通过在模型上添加同名的属性来使其工作,但同样,没有验证。

所以我的问题是,在 DRF 序列化器中嵌套(或分组)多个字段的最佳方法是什么?

DRF 3.0.0,Django 1.7

EDIT:

基于@Tom Christie 的回答,这就是我想出的(简化的)

# models.py
class BaseModel(models.Model):
  id = models.AutoField(primary_key=True)
  lat = models.FloatField(blank=True, null=True)
  lon = models.FloatField(blank=True, null=True)
  location_time = models.DateTimeField(blank=True, null=True)
  location_accuracy = models.FloatField(blank=True, null=True)
  location_provider = models.CharField(max_length=50, blank=True, null=True)

  @property
  def location(self):
    return {
      'lat': self.lat,
      'lon': self.lon,
      'location_time': self.location_time,
      'location_accuracy': self.location_accuracy,
      'location_provider': self.location_provider
    }

class ChildModel(BaseModel):
  name = models.CharField(max_lengtg=10)


# serializers.py
class LocationSerializer(serializers.Serializer):
  lat = serializers.FloatField(allow_null=True, required=False)
  lon = serializers.FloatField(allow_null=True, required=False)
  location_time = serializers.DateTimeField(allow_null=True, required=False)
  location_accuracy = serializers.FloatField(allow_null=True, required=False)
  location_provider = serializers.CharField(max_length=50,allow_null=True, required=False)


class BaseSerializer(serializers.ModelSerializer):

  def create(self,validated_data):
    validated_data.update(validated_data.pop('location',{}))
    return super(BaseSerializer,self).create(validated_data)

  def update(self, instance, validated_data):
    location = LocationSerializer(data=validated_data.pop('location',{}), partial=True)
    if location.is_valid():
      for attr,value in location.validated_data.iteritems():
        setattr(instance,attr,value)
    return super(BaseSerializer,self).update(instance, validated_data)

class ChildSerializer(BaseSerializer):
    location = LocationSerializer()

    class meta:
      model = ChildModel
      fields = ('name','location',)

我已经使用有效/无效的帖子/补丁进行了测试,效果非常好。

Thanks.


我建议简单地使用显式序列化器类,并显式编写字段。它有点冗长,但是简单、明显且可维护。

class LocationSerializer(serializers.Serializer):
    lat = serializers.FloatField()
    lon = serializers.FloatField()
    provider = serializers.CharField(max_length=100)
    accuracy = serializers.DecimalField(max_digits=3, decimal_places=1)

class FeatureSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=100)
    location = LocationSerializer()

    def create(self, validated_data):
        return Feature.objects.create(
            name=validated_data['name'],
            lat=validated_data['location']['lat'],
            lon=validated_data['location']['lat'],
            provider=validated_data['location']['provider'],
            accuracy=validated_data['location']['accuracy']
        )

    def update(self, instance, validated_data):
        instance.name = validated_data['name']
        instance.lat = validated_data['location']['lat']
        instance.lon = validated_data['location']['lat']
        instance.provider = validated_data['location']['provider']
        instance.accuracy = validated_data['location']['accuracy']
        instance.save()
        return instance

有很多方法你可以could use a ModelSerializer相反,或者保持的方法create and update方法稍微短一些,但不清楚您为自己提供的额外间接是否值得。

我们几乎always对我们正在构建的 API 使用完全显式的序列化器类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django Rest Framework - 如何在序列化器中嵌套多个字段? 的相关文章

随机推荐

  • 决赛选手有什么用?

    我已经用 NET 编程四年了 主要是 C 并且广泛使用 IDiposable 但我尚未发现需要终结器 决赛选手有什么用 终结器是确保正确清理某些内容的最后一搏 通常为包装对象保留不受管理的资源 例如非托管句柄等不会被垃圾收集 编写终结器确实
  • 设置 Git 远程 SSH (git-upload-pack / git-receive-pack)

    我有一台具有 SSH 访问权限的服务器 我想在那里放置一个 Git 原始存储库 我刚刚在本地创建了一个 bare shared 存储库 并将其复制到每个 SCP 的服务器上 现在我想根据 SSH url 克隆这个存储库 我试过 ssh US
  • PHP 将字符串转换为 slug

    将文本字符串转换为 slug 的最佳方法是什么 意义 允许使用 alpha 转换为小写 允许数字 应消除空格 而不是转换为破折号 重音字符被等效的标准字母替换 不允许使用其他字符 应将其删除 我在网上找到了大量代码 但它们都倾向于将空格转换
  • 熊猫:分组列出

    我有如下数据 id value time 1 5 2000 1 6 2000 1 7 2000 1 5 2001 2 3 2000 2 3 2001 2 4 2005 2 5 2005 3 3 2000 3 6 2005 我的最终目标是将数
  • 使用 jQueryUI 的新自动完成功能的多列结果的快速示例?

    我刚刚发现jQueryUI 现在拥有自己的内置自动完成组合框 好消息 不幸的是 我发现的下一件事是 使其成为多列似乎并不那么简单 至少通过文档 有一个在这里发帖有人提到他们已经做到了 甚至提供了代码 但我无法理解他们的一些代码在做什么 我只
  • SecItemAdd 和 SecItemCopyMatching 返回错误代码 -34018 (errSecMissingEntitlement)

    有时 当我从 Xcode 在设备上运行应用程序时 我会尝试访问钥匙串 但由于错误 34018 而失败 这与任何记录的钥匙串错误代码都不匹配 并且无法一致地重现 大概有 30 的时间发生 我不清楚为什么会发生 完全缺乏文档使得调试这个问题变得
  • 如何更改/更新/删除 Spring ConfigurableEnvironment 中的属性

    在 Spring 中 您可以使用注入环境对象来读取所有环境属性 Resource private org springframework core env Environment environment 所以问题是我可以以编程方式更改某些属
  • React 类中的清除间隔

    因此 我们有这个简单的 React 组件 它从父组件接收一个整数 单击该按钮后 我们会在屏幕上显示整数并开始倒计时 问题是如何停止倒计时 在阅读其他 SO 帖子时 我发现了clearInterval 但似乎我在这里遗漏了一些东西 任何帮助将
  • 无边框窗口无法正确最大化

    好吧 我已经在谷歌上搜索了几个小时了 似乎找不到我遇到的问题的直接答案 我有一个自定义窗口WindowStyle None and AllowsTransparency True 当我点击最大化按钮时 private void Maximi
  • 检测phonegap应用程序中的卸载事件

    当用户安装我的应用程序时 我注册他的注册 ID android 或设备令牌 iOS 并发送工作正常的推送通知 但现在我想在卸载应用程序时从服务器中删除用户 如何在 Phonegap 中完成此操作 获取一个事件 之后我可以取消注册用户注册 I
  • 在 Django 模型中存储列表最有效的方法是什么?

    目前我的代码中有很多类似于以下内容的 python 对象 class MyClass def init self name friends self myName name self myFriends str x for x in fri
  • 计算 BST 中左节点的数量

    给定 BST 我需要找到树的左节点数 示例 3 5 2 1 4 6 7 答案应该是 4 因为 5 1 4 7 都是树的左节点 我想做的是 public int countL
  • R 中的 par(mfrow) 用于 ggplot [重复]

    这个问题在这里已经有答案了 我有这个代码 plotfn function u flt filter d utensil u ggplot flt aes x p geom histogram binwidth 0 5 position po
  • MySQL - 强制不使用缓存来测试查询速度

    我正在测试 MySQL 中某些查询的速度 数据库正在缓存这些查询 这使得我在测试这些查询的速度时很难获得可靠的结果 有没有办法禁用查询缓存 系统 Linux 虚拟主机上的 MySQL 4 我可以访问 PHPMyAdmin Thanks 尝试
  • Ruby gem mysql2 安装失败[重复]

    这个问题在这里已经有答案了 当我尝试安装 mysql2 gem 时 它失败了 没有明显的错误 有谁知道如何解决这个问题以便安装mysql2 sudo gem install mysql2 Building native extensions
  • “multipart/form-data”POST 请求实际上应该包含带有上传图像数据的字符串吗?

    我正在为一个 Web 应用程序创建一些性能测试 该应用程序发送的请求类型与浏览器发送到我们的服务器的类型相同 其中一个请求是上传图像的 POST 我在看这个问题看起来图像文件的实际内容应该位于请求正文内 然而 当我在 Chrome 中使用
  • 如何检查设备是否为 iPad 或 iPhone 无法正常工作

    我目前正在更新一个应用程序 我需要知道该应用程序是否正在 iPad 上使用 我上网查了一下 发现了下面的代码 我在 Xcode 中使用了 iPad 模拟器并运行了两个 if 语句 但是每当我运行代码时 什么也没有发生 打印消息不打印 此代码
  • 密封一个类

    过去我并没有太在意封闭班级 但我发现自己想知道最好的做法是什么 如果您知道一个类不会或不应该从中派生 您是否会将其密封 作为预防措施 只是将密封关键字保留在外 因为知道有人尝试从中派生的机会很小 我想我要问的是 您是否应该密封所有不打算用于
  • 如何将 EC2 实例分配给子网内的固定 IP 地址?

    我正在使用 CloudFormation 定义子网和 EC2 实例 我想为 EC2 实例分配特定的私有 IP 地址 并尝试使用如下资源定义来实现此目的 当我尝试部署模板时 NetworkInterface 资源的创建失败并显示以下消息 地址
  • Django Rest Framework - 如何在序列化器中嵌套多个字段?

    我有几个带有多个控制字段的基本模型 其中位置字段由纬度 经度 精度 提供商和客户时间组合而成 我的大多数可写模型 以及资源 都是从这个基本模型继承的 我试图让 DRF 序列化嵌套 位置 字段中的位置相关字段 例如 id 1 name Som