Django REST: как предотвратить сериализацию значения поля конкретной модели? - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть такая модель:

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, чтобы предотвратить сериализацию только поля value из textjson?

Возможно, я будунужно переопределить to_representation и to_internal_value методы поля, но как?

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

вы можете определить 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__'
0 голосов
/ 20 декабря 2018

Использование serializers.JSONField() решит проблему,

class TestSerializer(serializers.ModelSerializer):
    <b>textjson = serializers.JSONField() # here &lt&lt&lt&lt&lt</b>

    class Meta:
        model = Test
        fields = '__all__'
0 голосов
/ 20 декабря 2018

Я нашел способ.Нужно написать настраиваемое поле сериализатора и переопределить его 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...