【问题标题】:How to take info from sub-object in request before validating in Django?如何在 Django 中验证之前从请求中的子对象获取信息?
【发布时间】:2019-07-12 16:45:49
【问题描述】:

我正在 Django 中编写一个 API,为此我使用 django-rest-framework。我有一个简单的模型如下:

class PeopleCounter(models.Model):
    version = models.CharField(max_length=10)
    timestamp = models.DateTimeField(db_index=True)
    sensor = models.CharField(max_length=10)
    count = models.IntegerField()

我有一个序列化器如下:

class PeopleCounterSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = PeopleCounter
        fields = [
            'version',
            'timestamp',
            'sensor',
            'count',
        ]

当我将以下数据发布到此端点时,效果很好:

{
    "version": "v1",
    "timestamp": "2019-04-01T20:00:00.312",
    "sensor": "sensorA",
    "count": 4
}

但不幸的是,我需要调整端点以使数据到达如下:

{
    "version": "v1",
    "timestamp": "2019-04-01T20:00:00.312",
    "data": {
        "sensor": "sensorA",
        "count": 4
    }
}

我认为我需要向序列化程序类添加一个创建方法。所以我尝试了,但是当我使用 "data" 对象发布 json 时,我收到一条消息,提示传感器字段和计数字段是必需的。

有人知道我可以在哪里规范化这些数据,以便我可以将其正确插入数据库吗?

另外,如果我也想通过同样的端点提供数据,我可以在哪里定义呢?

欢迎所有提示!

【问题讨论】:

    标签: json django serialization django-rest-framework


    【解决方案1】:

    一种可能的方法是在视图级别实现它。如果您使用 CBV 覆盖 get_serializer 类似这样:

    def get_serializer(self, *args, **kwargs):
        request_body = kwargs.get("data")  # obtain request body
        data = request_body.get("data")  # get data
        request_body.update(data)  # add data as request_body attributes
        kwargs["data"] = request_body  # override received request_body with updated one
    
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)
    

    【讨论】:

    • 由于我是 Django 初学者,我花了一些时间才明白 CBV 的意思是“基于类的视图”以及我必须把它放在哪里,但我做到了,现在它工作得很好!还有一件事;你知道我如何再次使用相同的结构通过 api 提供这个服务(所以在"data" 中使用sensorcount)?
    • @kramer65 如果您需要将此逻辑扩展到多个视图,您可以尝试在自定义解析器中进行:django-rest-framework.org/api-guide/parsers/#custom-parsers
    • @kramer65 添加自定义中间件是我相信的另一个选项docs.djangoproject.com/en/2.2/topics/http/middleware
    猜你喜欢
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 2022-08-08
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 2017-02-25
    • 2018-06-29
    相关资源
    最近更新 更多