Djago-gis: Не удается сериализовать словарь с помощью GeoFeatureModelSerializer: KeyError: 'id', даже при .is_valid=True и исключении id

Я пытаюсь создать прототип представления, получающего некоторый geojson. Я использую jupyter notebook, с (https://gist.github.com/codingforentrepreneurs/76e570d759f83d690bf36a8a8fa4cfbe)[скрипт init_django в этой ссылке). Пытаюсь сериализовать этот geojson (который был преобразован в dict)

{'id': '0',
 'type': 'Feature',
 'properties': {'area': 0.74,
  'gloc1': sensitive,
  'gloc2': sensitive,
  'gloc3': sensitive,
  'gloc4': sensitive,
  'gloc5': sensitive},
 'geometry': {'type': 'MultiPolygon',
  'coordinates': [some_coordinates]}}

У меня возникают проблемы с некоторым полем id.

Вот сериализатор модели, использующий библиотеку rest_framework_gis.

class Local(GeoFeatureModelSerializer):

    # cliente = PrimaryKeyRelatedField(queryset=ClienteModel.objects.all())
    class Meta:
        model = LocalModel
        fields = "__all__"
        geo_field = "geom"

Вот модель, которую я использую из django.contrib.gis.db.models import Model

class Local(Model):

    status_choice = TextChoices('status', 'ATIVO INATIVO PONTUAL')

    gloc1 = TextField(null=False)
    gloc2 = TextField(null=False)
    gloc3 = TextField(null=False)
    gloc4 = TextField(null=False)
    gloc5 = TextField(null=False)
    latitude = FloatField(null=True, blank=True)
    longitude = FloatField(null=True, blank=True)
    altimetria = FloatField(null=True, blank=True)
    capacidade_retencao_agua = FloatField(null=True, blank=True)
    coef_textura_agua_solo = FloatField(null=True, blank=True)
    coef_potencia_agua_solo = FloatField(null=True, blank=True)
    sk1m = FloatField(null=True, blank=True, default=0)
    sk2m = FloatField(null=True, blank=True, default=1)
    smaw = FloatField(null=True, blank=True, default=0)
    sfer = FloatField(null=True, blank=True, default=1)
    profundidade_efetiva_maxima = FloatField(null=True, blank=True)
    cti = FloatField(null=True, blank=True)
    slo = FloatField(null=True, blank=True)
    geom = GeometryField(srid=4326, null=False)
    data_criacao = DateField(auto_now=True)
    data_atualizacao = DateField(auto_now_add=True)
    #null-False here
    cena_s2 = TextField(null=True, blank=True)
    area = FloatField(null=True, blank=True)
    grupo = IntegerField(null=True, blank=True)
    status = TextField(null=True, choices=status_choice.choices)
    objects: LocalQuerySet = LocalManager.from_queryset(LocalQuerySet)()
    glocs: GlocLocalQuerySet = GlocLocalManager.from_queryset(GlocLocalQuerySet)()

Здесь я загружаю данные. Обратите внимание, что сериализатор показывает, что это правильный geojson.

s = Local(data=data)
#True
s.is_valid(raise_exception=True)
s.data

Но появляется ошибка id

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/fields.py:454, in Field.get_attribute(self, instance)
    453 try:
--> 454     return get_attribute(instance, self.source_attrs)
    455 except BuiltinSignatureError as exc:

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/fields.py:92, in get_attribute(instance, attrs)
     91 if isinstance(instance, Mapping):
---> 92     instance = instance[attr]
     93 else:

KeyError: 'id'

During handling of the above exception, another exception occurred:

SkipField                                 Traceback (most recent call last)
/home/elysium/Documents/c/projects/apis/gpt/nbs/local_serializer.ipynb Cell 4' in <cell line: 4>()
      2 #True
      3 s.is_valid(raise_exception=True)
----> 4 s.data

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/serializers.py:562, in Serializer.data(self)
    560 @property
    561 def data(self):
--> 562     ret = super().data
    563     return ReturnDict(ret, serializer=self)

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/serializers.py:262, in BaseSerializer.data(self)
    260     self._data = self.to_representation(self.instance)
    261 elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
--> 262     self._data = self.to_representation(self.validated_data)
    263 else:
    264     self._data = self.get_initial()

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework_gis/serializers.py:104, in GeoFeatureModelSerializer.to_representation(self, instance)
    102 if self.Meta.id_field:
    103     field = self.fields[self.Meta.id_field]
--> 104     value = field.get_attribute(instance)
    105     feature["id"] = field.to_representation(value)
    106     processed_fields.add(self.Meta.id_field)

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/fields.py:473, in Field.get_attribute(self, instance)
    471     return None
    472 if not self.required:
--> 473     raise SkipField()
    474 msg = (
    475     'Got {exc_type} when attempting to get a value for field '
    476     '`{field}` on serializer `{serializer}`.\nThe serializer '
   (...)
    485     )
    486 )
    487 raise type(exc)(msg)

SkipField: 

На этот раз я пробую исключить поле id из сериализатора, но появляется немного другая ошибка

class Local(GeoFeatureModelSerializer):

    # cliente = PrimaryKeyRelatedField(queryset=ClienteModel.objects.all())
    class Meta:
        model = LocalModel
        exclude = ['id']
        geo_field = "geom"
KeyError                                  Traceback (most recent call last)
/home/elysium/Documents/c/projects/apis/gpt/nbs/local_serializer.ipynb Cell 4' in <cell line: 4>()
      2 #True
      3 s.is_valid(raise_exception=True)
----> 4 s.data

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/serializers.py:562, in Serializer.data(self)
    560 @property
    561 def data(self):
--> 562     ret = super().data
    563     return ReturnDict(ret, serializer=self)

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/serializers.py:262, in BaseSerializer.data(self)
    260     self._data = self.to_representation(self.instance)
    261 elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
--> 262     self._data = self.to_representation(self.validated_data)
    263 else:
    264     self._data = self.get_initial()

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework_gis/serializers.py:103, in GeoFeatureModelSerializer.to_representation(self, instance)
    101 # optional id attribute
    102 if self.Meta.id_field:
--> 103     field = self.fields[self.Meta.id_field]
    104     value = field.get_attribute(instance)
    105     feature["id"] = field.to_representation(value)

File ~/Documents/c/projects/apis/gpt/venv/lib/python3.9/site-packages/rest_framework/utils/serializer_helpers.py:148, in BindingDict.__getitem__(self, key)
    147 def __getitem__(self, key):
--> 148     return self.fields[key]

KeyError: 'id'

Удаление поля id в geojson также приводит к той же ошибке, что и выше. Может я что-то упускаю? Сценарий init_notebook работает довольно хорошо, django инициализируется и подключается к базе данных.

Вернуться на верх