Django REST:如何防止特定模型字段的值被序列化?

时间:2018-12-19 19:48:19

标签: python django django-rest-framework

我有一个这样的模型:

class Test(models.Model):
    textjson = models.TextField(default="Unassigned")

字段textjson将JSON作为字符串保存:

`'{"distance": 31702.1, "link": "www.strava.com/activities/2020494234", "athlete": 1, "average_speed": 6.499, "name": "Afternoon Ride", "start_date": "2018-12-16T12:13:42Z", "country": "Poland", "number": 2020494234, "date_added": "2018-12-16T20:14:01.362215Z"}`'

我已经为此模型构建了一个API视图:

class ListTestsView(generics.ListAPIView):
    serializer_class = TestSerializer

    def get_queryset(self):
        tests = Test.objects.all()
        return tests

我正在像这样序列化模型:

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = Test
        fields = '__all__'

但是,这会使jsontext字段在调用API视图并出现反斜杠时再次被序列化:

[
    {
        "id": 1,
        "textjson": "{\"distance\": 31702.1, \"link\": \"www.strava.com/activities/2020494234\", \"athlete\": 1, \"average_speed\": 6.499, \"name\": \"Afternoon Ride\", \"start_date\": \"2018-12-16T12:13:42Z\", \"country\": \"Poland\", \"number\": 2020494234, \"date_added\": \"2018-12-16T20:14:01.362215Z\"}"
    }
]

如何重写TestSerializer类,以防止仅textjson字段的 被序列化?

我可能需要重写该字段的to_representationto_internal_value方法,但是如何?

3 个答案:

答案 0 :(得分:0)

我找到了一种方法。需要编写一个自定义序列化器字段并覆盖其to representation方法:

class CustomJSONField(serializers.Field):
    """Converts only value, not name, of a field into Javascript-friendly JSON,
     not Python object or backslashed JSON. Simply avoiding the field value,
     which is a string already, being serialized again"""
    def to_representation(self, value):
        return json.loads(value)

class TestSerializer(serializers.ModelSerializer):
    textjson = CustomJSONField()
    class Meta:
        model = Test
        fields = '__all__'

并且如果存储在字段中的JSON是字典列表的字符串表示形式,则可以执行以下操作:

import ast

class CustomJSONField(serializers.Field):
    def to_representation(self, value):
        return ast.literal_eval(value)

答案 1 :(得分:0)

您可以定义serializers.SerializerMethodField()。它将返回新字段textjson_original,如下所示:

    from rest_framework import serializers
    class TestSerializer(serializers.ModelSerializer):
        textjson_original = serializers.SerializerMethodField()
        @staticmethod
        def get_textjson_original(item):
            return item.textjson
        class Meta:
            model = Test
            fields = '__all__'

答案 2 :(得分:0)

使用serializers.JSONField()可以解决问题,

class TestSerializer(serializers.ModelSerializer):
    textjson = serializers.JSONField() # here <<<<<

    class Meta:
        model = Test
        fields = '__all__'