Skip to content
Advertisement

Object of type BoundField is not JSON serializable

A have a chain of OneToMany relations (one) Construction -> Camera -> Frame -> Event

models.py

def name_image(instance, filename):
    return '/'.join(['images', str(instance.name), filename])


class Construction(models.Model):
    """ Объект строительства"""
    developer = models.ForeignKey(
        Developer, related_name="constructions", on_delete=models.CASCADE
    )
    name = models.CharField(max_length=100)
    plan_image = models.ImageField(upload_to=name_image, blank=True, null=True)
    address = models.CharField(max_length=100)
    coordinates = models.PointField(blank=True)
    deadline = models.DateTimeField(default=timezone.now, )
    workers_number = models.IntegerField(default=0)
    machines_number = models.IntegerField(default=0)

    def __str__(self):
        return self.name

class Camera(models.Model):
    building = models.ForeignKey( # not important
        Construction, related_name="cameras", on_delete=models.CASCADE
    )
    name = models.CharField(max_length=100)
    url = models.CharField(max_length=100)
    ...

class Frame(models.Model):
    """ Фото с камеры """
    camera_id = models.ForeignKey(
        Camera, related_name="frames", on_delete=models.CASCADE
    )
    ...
class Event(models.Model):
    frame_id = models.ForeignKey(
        Frame, related_name="events", on_delete=models.CASCADE
    )
    ...

I want to output data about Camera in EventSerializer (GET method). I am using get_construction method I want to use ConstructionSerializer for Construction object ( <class ‘api_buildings.models.Construction’>)

But I have an error

Object of type BoundField is not JSON serializable

How can I fix this error (I know, that I can use model_to_dict, but I want to use ConstructionSerializer)

class EventSerializer(serializers.ModelSerializer):
    time = serializers.DateTimeField(format=TIME_FORMAT)
    camera = serializers.SerializerMethodField()
    construction = serializers.SerializerMethodField()
    frame = serializers.SerializerMethodField()
    developer = serializers.SerializerMethodField()

    class Meta:
        model = Event
        fields = (
            'id', 'frame_id', 'frame', 'developer', 'camera', 'construction', 'type_of_event', 'class_name',
            'grn', 'track_id', 'bounding_coords', 'time'
        )


    def create(self, validated_data):
        instance = super().create(validated_data=validated_data)
        return instance

    def get_construction(self, obj):
        buiding = obj.frame_id.camera_id.building
        print(type(buiding)) # <class 'api_buildings.models.Construction'>
        return ConstructionSerializer(buiding) 

Full error log (may be usefull)

Internal Server Error: /api/events/
Traceback (most recent call last):
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 204, in _get_response
    response = response.render()
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/djangorestframework_camel_case/render.py", line 17, in render
    camelize(data, **api_settings.JSON_UNDERSCOREIZE), *args, **kwargs
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/renderers.py", line 724, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/renderers.py", line 680, in get_context
    'content': self.get_content(renderer, data, accepted_media_type, renderer_context),
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/renderers.py", line 413, in get_content
    content = renderer.render(data, accepted_media_type, renderer_context)
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/djangorestframework_camel_case/render.py", line 10, in render
    camelize(data, **api_settings.JSON_UNDERSCOREIZE), *args, **kwargs
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/renderers.py", line 103, in render
    allow_nan=not self.strict, separators=separators
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/utils/json.py", line 25, in dumps
    return json.dumps(*args, **kwargs)
  File "/home/alex/anaconda3/lib/python3.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 201, in encode
    chunks = list(chunks)
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 431, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 325, in _iterencode_list
    yield from chunks
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 438, in _iterencode
    o = _default(o)
  File "/home/alex/root_folder/projects/38_safe_building/1_code/buildings/back/api/venv/lib/python3.7/site-packages/rest_framework/utils/encoders.py", line 67, in default
    return super().default(obj)
  File "/home/alex/anaconda3/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type BoundField is not JSON serializable

Advertisement

Answer

Seems you forgot to use .data:

return ConstructionSerializer(buiding).data
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement