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