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

后端 未结 3 2189
孤街浪徒
孤街浪徒 2021-01-05 23:20

I am pretty new to the django-rest-framework, so could use some help.

I have an object with a TextField that is a string containing JSON.

I\'m using django-r

相关标签:
3条回答
  • 2021-01-06 00:00

    You can simply decode the json into python object:

    json_obj = json.loads(model.json_text)
    

    Once you serialize your object, replace this field with the decoded object:

    data = serializer.data
    data["field"] = json_obj
    return Response(data)
    
    0 讨论(0)
  • 2021-01-06 00:06

    I solved this another way:

    1: use a JSON-Field for the JSON content (django-jsonfield or django-json-field should be fine). These then will to loads/dumps as needed

    2: in my serializer, use the transform-method to prevent the data added as string to the response

    class MyModelSerializer(serializers.ModelSerializer):
        def transform_myjsonfield(self, obj, value):
            return obj.myjsonfield
    
        class Meta:
            model = MyModel
    

    If you need write-access, you only have to add a method validate_myjsonfield which converts back.

    (of course, this could be also done with a custom DRF serializer field.

    0 讨论(0)
  • 2021-01-06 00:08

    Here is what works for me on, djangorestframework==3.9.1:

    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', ]
    

    I thought there would be an easier way to do this, but by changing the behaviour of to_representation, I can convert my text fields to JSON. For reference, here is my models.py:

    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)
    

    Hope that helps. If you use a JSONField that is supported by Postgres, I'm sure you won't need to do this. I'm using a TextField to save my JSON here. I thought that specifying the field type as serializers.JSONField on the serializer would be enough but its not the case.

    0 讨论(0)
提交回复
热议问题