关于python:django-rest-framework:如何序列化已经包含JSON的字段?

django-rest-framework: How Do I Serialize a Field That Already Contains JSON?

我对django-rest-frame相当陌生,因此可以使用一些帮助。

我有一个TextField对象,该对象是一个包含JSON的字符串。

我正在使用django-rest-framework将整个对象序列化为JSON。但是,已经为JSON的一个字符串被序列化为包含JSON而不是JSON本身的编码字符串。

如何告诉序列化程序按原样发送此字段,而不是尝试将此字符串转换为JSON?我可以使用某种"忽略"装饰器或替代方法吗?还是可以在序列化之前预解析此JSON?

这是具有以下内容的区别:

1
{"data": data}

1
{"data":"data"}

后者在客户端使用时比较麻烦...


我用另一种方式解决了这个问题:

1:对JSON内容使用JSON字段(django-jsonfielddjango-json-field应该没问题)。然后,这些将根据需要加载/转储

2:在我的序列化程序中,使用transform-method来防止将数据作为字符串添加到响应中

1
2
3
4
5
6
class MyModelSerializer(serializers.ModelSerializer):
    def transform_myjsonfield(self, obj, value):
        return obj.myjsonfield

    class Meta:
        model = MyModel

如果需要写访问权限,只需添加一个方法validate_myjsonfield即可转换回去。

(当然,这也可以通过自定义DRF序列化器字段来完成。


您可以简单地将json解码为python对象:

1
json_obj = json.loads(model.json_text)

序列化对象后,将此字段替换为已解码的对象:

1
2
3
data = serializer.data
data["field"] = json_obj
return Response(data)


这是对我有效的djangorestframework==3.9.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import json

from rest_framework import serializers

from .models import WeatherLocation


class WeatherLocationSerializer(serializers.ModelSerializer):
    LocationId = serializers.CharField(source='location_id')
    City = serializers.CharField(source='city')
    Region = serializers.CharField(source='region')
    Name = serializers.CharField(source='name')
    Country = serializers.CharField(source='country')
    WeatherForecastLongTermTimePeriods = serializers.JSONField(required=False, allow_null=True,
                                                               source='weather_forecast_long_term_time_periods')
    WeatherForecastShortTermTimePeriods = serializers.JSONField(required=False, allow_null=True,
                                                                source='weather_forecast_short_term_time_periods')

    def to_representation(self, instance):
        ret = super(WeatherLocationSerializer, self).to_representation(instance)
        ret['WeatherForecastLongTermTimePeriods'] = json.loads(ret['WeatherForecastLongTermTimePeriods'])
        ret['WeatherForecastShortTermTimePeriods'] = json.loads(ret['WeatherForecastShortTermTimePeriods'])
        return ret

    class Meta:
        model = WeatherLocation
        fields = ['LocationId', 'City', 'Region', 'Name', 'Country',
                  'WeatherForecastLongTermTimePeriods', 'WeatherForecastShortTermTimePeriods', ]

我认为会有一个更简单的方法来执行此操作,但是通过更改to_representation的行为,我可以将文本字段转换为JSON。供参考,这是我的models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.db import models


class WeatherLocation(models.Model):
   """
    Weather app schema, from southparc
   """

    location_id = models.CharField(primary_key=True, null=False, blank=False, default=None, max_length=254,
                                   editable=True)
    region = models.CharField(max_length=2, null=False, blank=False)
    city = models.CharField(null=False, blank=False, max_length=254)
    province = models.CharField(null=True, blank=True, max_length=254)
    name = models.CharField(null=True, blank=True, max_length=254)
    country = models.CharField(null=True, blank=True, max_length=254)

    # JSON fields
    weather_forecast_long_term_time_periods = models.TextField(default="", blank=True)
    weather_forecast_short_term_time_periods = models.TextField(default="", blank=True)

    # Dates
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)

希望有帮助。如果您使用Postgres支持的JSONField,我确定您不需要这样做。我正在使用TextField在此处保存我的JSON。我认为在序列化程序上将字段类型指定为serializers.JSONField就足够了,但事实并非如此。