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

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

class Activity(models.Model):
    date_added = models.DateTimeField(auto_now_add=True)
    start_date = models.DateTimeField(default=datetime.datetime.now)
    data = models.TextField() # stores activity's JSON in text format, not as Python object
    number = models.IntegerField(default=0)
    athlete = models.ForeignKey(Athlete, on_delete=models.CASCADE, default=None)

Поле data сохраняет JSON как текст .

Я использую следующий сериализатор для этой модели:

from rest_framework import serializers
from .models import Activity


class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity
        fields = ("date_added", "start_date", "data", "number", "athlete")

Теперь, когда я делаю следующее в оболочке Django:

>>>from explorer_api.models import Activity
>>>fromt explorer_api.serializers import ActivitySerializer
>>>activity = Activity.objects.latest('id')
>>>serializer = ActivitySerializer(activity)
>>>serializer.data

Вывод генерируется нормально:

>>> serializer.data
{'date_added': '2018-11-19T21:10:29.324522Z', 'start_date': '2018-11-15T05:36:10Z', 'athlete': 1, 'data': '{"resource_state":3,"athlete":{"id":3255732,"resource_state":1},"name":"Morning Ride","distance":33605.0,"moving_time":5067,"elapsed_time":5067,"total_elevation_gain":59.0,

Однако, когда я пытаюсь использовать рендерер JSON:

>>>from rest_framework.renderers import JSONrenderer
>>>JSONRenderer.render(serializer.data)

activity.data визуализируется с обратной косой чертой, чтобы избежать двойных кавычек:

>>> JSONRenderer().render(serializer.data)
b'{"date_added":"2018-11-19T21:10:29.324522Z","start_date":"2018-11-15T05:36:10Z","data":"{\\"resource_state\\":3,\\"athlete\\":{\\"id\\":3255732,\\"resource_state\\":1},\\"name\\":\\"Morning Ride\\",\\"distance\\":33605.0,

Как я могу предотвратить это? Я хочу, чтобы мой API предоставлял чистый текст в формате JSON.

1 Ответ

0 голосов
/ 19 ноября 2018

Вы можете переопределить serializers.Field, чтобы создать новый SerilizerField и изменить его поведение . Например:

import json

class JSONSerializerField(serializers.Field):

    def to_representation(self, obj):
        try:
            return json.loads(obj)
        except (ValueError, Exception) as e:
            # log exception
            return obj

    def to_internal_value(self, data):
        return data

class ActivitySerializer(serializers.HyperlinkedModelSerializer):
    data = JSONSerializerField()

    class Meta:
        model = Activity
        fields = ('data', 'id', 'date_added', 'start_date')
...