Django : "соответствующий запрос не существует" в методе save()
Я создаю приложение, которое извлекает данные из API и заполняет БД полученными данными.
Я пытаюсь сохранить в DB каждую обработанную строку JSON. Когда я вызываю obj_to_insert.save() в конце, я получаю ошибку: geotrek.trekking.models.DoesNotExist: POI matching query does not exist. POI является одной из моих моделей, она правильно определена и импортирована.
Вот структура функции обработки (я слишком упростил ее, все переменные, которые я использую, правильно определены в реальном коде, и т.д.):
with transaction.atomic():
for datatype_name, datatype_details in dict.items():
##fetching the API
r = response.json()["results"]
for index in range(len(r)):
dict_to_insert = {}
for f in normal_fields:
dict_to_insert[f.name] = other_dict['key'][f.name]
obj_to_insert = DataType(**dict_to_insert)
for f in fkeys_fields:
fk_to_insert = {}
if condition:
fk_to_insert[f.name] = other_dict['key'][f.name]
new_topo = Topology.objects.create(**fk_to_insert)
obj_to_insert.topo_object = new_topo
elif condition:
obj_to_insert.structure = Structure.objects.get(name = AUTHENT_STRUCTURE)
elif condition:
fk_to_insert[f.name] = other_dict['key'][f.name] ##simplified
setattr(obj_to_insert, fk_field, f.related_model.objects.get(**fk_to_insert))
obj_to_insert.save()
Все идет хорошо до финального .save(), который выдает ошибку models.DoesNotExist. Как будто Django получает obj_to_insert, пытается найти соответствующую строку в БД и не находит ее (нормально: я пытаюсь создать ее).
Когда я print(vars(obj_to_insert)) непосредственно перед попыткой сохранения, вот вывод, который выглядит совершенно нормально для меня:
{'_state': <django.db.models.base.ModelState object at 0x7f2cd58ab0a0>, 'id': 84909, 'date_insert': None, 'date_update': None, 'deleted': False, 'geom_3d': None, 'length': 0.0, 'ascent': 0, 'descent': 0, 'min_elevation': 0, 'max_elevation': 0, 'slope': 0.0, 'offset': 0.0, 'kind': 'POI', 'geom_need_update': False, 'geom': None, 'uuid': UUID('6e37ea3e-ec49-4eab-a719-6037b3d61ccb'), 'structure_id': 7, 'published': True, 'published_en': False, 'published_fr': True, 'publication_date': None, 'name': 'Refuge de la Lavey', 'name_en': '', 'name_fr': 'Refuge de la Lavey', 'review': False, 'topo_object_id': 84909, 'description': 'Test refuge', 'description_en': '', 'description_fr': 'Test refuge', 'type_id': 8, 'eid': None}
Вот полное сообщение об ошибке:
Traceback (most recent call last):
File "/usr/sbin/geotrek", line 20, in <module>
execute_from_command_line(sys.argv)
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
self.execute(*args, **cmd_options)
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
output = self.handle(*args, **options)
File "/opt/geotrek-admin/lib/python3.8/site-packages/geotrek/common/management/commands/import.py", line 55, in handle
parser.parse(options['shapefile'], limit=limit)
File "/opt/geotrek-admin/var/conf/parsers.py", line 17, in parse
spec.loader.exec_module(module)
File "<frozen importlib._bootstrap_external>", line 848, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/opt/geotrek-admin/var/conf/gag_app/custom_geotrek_shell.py", line 169, in <module>
test()
File "/opt/geotrek-admin/var/conf/gag_app/custom_geotrek_shell.py", line 166, in test
obj_to_insert.save()
File "/opt/geotrek-admin/lib/python3.8/site-packages/geotrek/trekking/models.py", line 744, in save
super().save(*args, **kwargs)
File "/opt/geotrek-admin/lib/python3.8/site-packages/geotrek/common/mixins.py", line 282, in save
super().save(*args, **kwargs)
File "/opt/geotrek-admin/lib/python3.8/site-packages/geotrek/common/utils/postgresql.py", line 23, in wrapped
r = f(*args, **kwargs)
File "/opt/geotrek-admin/lib/python3.8/site-packages/geotrek/core/models.py", line 574, in save
existing = self.__class__.objects.get(pk=self.pk)
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/opt/geotrek-admin/lib/python3.8/site-packages/django/db/models/query.py", line 429, in get
raise self.model.DoesNotExist(
geotrek.trekking.models.DoesNotExist: POI matching query does not exist.
Я что-то упустил при использовании метода save(), или при работе с заполнением внешних ключей?
Проблема заключалась в моем порядке обработки. Поскольку POI является дочерним объектом Topology, я не могу создать объект POI и связать его с объектом POI, созданным после этого. Поскольку я перевел свое приложение с SQLAlchemy, логика для такого рода вещей отличается.