#python #django #geodjango
#python #django #geodjango
Вопрос:
Используя ogrinfo -so
, я нашел структуру шейп-файла и на основе этой структуры создал модель:
from django.contrib.gis.db import models
class Villages(models.Model):
.
.
.
После этого я создал, load.py
как указано здесь, в том же каталоге models.py
:
from pathlib import Path
from django.contrib.gis.utils import LayerMapping
from .models import Villages
villages_mapping = {
.
.
.
}
villages = Path(__file__).resolve().parent / 'gis' / 'villages.shp'
def run(verbose=True):
lm = LayerMapping(Villages, villages, villages_mapping, transform=False)
lm.save(strict=True, verbose=verbose)
Затем я пытаюсь использовать load.py
:
python3 manage.py shell
> from geodata import load
> load.run()
Но я вижу эту странную ошибку:
Traceback (most recent call last): File "<console>", line 1, in
<module> File
"/home/maxdragonheart/DEV_FOLDER/Django/Enographiae/enographiae_dev/enographiae/geodata/load.py", line 32, in run
lm = LayerMapping(Villages, villages, villages_mapping, transform=False) File
"/home/maxdragonheart/DEV_FOLDER/Django/Enographiae/enographiae_dev/devenv/lib/python3.7/site-packages/django/contrib/gis/utils/layermapping.py", line 99, in __init__
self.layer = self.ds[layer] TypeError: 'PosixPath' object is not subscriptable
Редактировать:
Возможно, проблема внутри layermapping.py
. Я воспроизвел учебник, используя исходный код и данные, и я вижу это:
File "<console>", line 1, in <module>
File "/home/maxdragonheart/DEV_FOLDER/Django/Singole APP/GeoDjango/webgis/tutorialgeodjango/load.py", line 23, in run
lm = LayerMapping(WorldBorder, world_shp, world_mapping, transform=False)
File "/home/maxdragonheart/DEV_FOLDER/Django/Singole APP/GeoDjango/devenv/lib/python3.7/site-packages/django/contrib/gis/utils/layermapping.py", line 100, in __init__
self.layer = self.ds[layer]
TypeError: 'PosixPath' object is not subscriptable
РЕДАКТИРОВАТЬ 2:
Используя код из Django 2.2, у меня нет проблем с загрузкой данных. Как я могу сообщить об этой ошибке?
РЕДАКТИРОВАТЬ 3:
Проблема также в Django 3.1.3
Комментарии:
1. что такое PosixPath и где вы его использовали?
2. В этом проблема. Я не знаю, что это
PosixPath
такое. Я просто скопировал и вставил код из официального руководства3. Я думаю, все, что вам нужно сделать, это преобразовать path в string, потому что вы используете
Path
, а Django ожидает либо path какstr
, либоDataSource
instance . Изменитеvillages
наstr(villages)
и будем надеяться, что это все 🙂4. Если вы добавите это в качестве ответа, я могу проголосовать за вас @Borut
5. Спасибо. Я добавил ответ с полным объяснением.
Ответ №1:
Документация Django для LayerMapping API не на 100% ясна в отношении типа данных для path, но если вы проверите исходный код, вы увидите, что он ожидает либо экземпляр string, либо экземпляр DataSource .
Ниже приведен соответствующий код из исходного кода.
def __init__(self, model, data, mapping, layer=0,
source_srs=None, encoding='utf-8',
transaction_mode='commit_on_success',
transform=True, unique=None, using=None):
"""
A LayerMapping object is initialized using the given Model (not an instance),
a DataSource (or string path to an OGR-supported data file), and a mapping
dictionary. See the module level docstring for more details and keyword
argument usage.
"""
# Getting the DataSource and the associated Layer.
if isinstance(data, str):
self.ds = DataSource(data, encoding=encoding)
else:
self.ds = data
self.layer = self.ds[layer]
В комментарии упоминается путь к строке, а позже в коде есть проверка, является ли data
аргумент строкой (в данном случае path) при инициализации DataSource
экземпляра с его помощью.
Простое изменение Path
на str
решит вашу проблему.
lm = LayerMapping(Villages, str(villages), villages_mapping, transform=False)