导入前解析 django-import-export 中的字段
Parsing fields in django-import-export before importing
我正在使用 django-import-export 包来获取包含位置名称及其经纬度的 csv 文件。
我想从 csv 中解析经度和纬度字段,将它们转换为 django.contrib.gis.geos.Point
对象,以便我可以将其输入到我的 Location
模型的 geom
字段中。
# models.py
from django.contrib.gis.db import models
class Location(models.Model):
name = models.CharField(max_length=200)
geom = models.PointField(null=True, blank=True)
def __str__(self):
return self.name
# admin.py
from .models import Location
from import_export import resources
from import_export.admin import ImportExportModelAdmin
class LocationResource(resources.ModelResource):
geom = Field()
latitude = Field()
longitude = Field()
class Meta:
model = Location
fields = ('id','name', 'latitude', 'longitude')
exclude = ('geom')
export_order = ('id', 'name', 'latitude', 'longitude')
def dehydrate_geom(self, data):
return Point(data.longitude, data.longitude)
class LocationAdmin(ImportExportModelAdmin):
resource_class = LocationResource
admin.site.register(Location, LocationAdmin)
这是我取得的进展,但没有成功。
必须有:
Location(name='name', geom=Point(longitude, latitude))
CSV 文件:locations.csv
id,name,longitude,latitude
1,Naga,120.18,18.20
更新 1
尝试使用 hydrate_<field_name>
但没有成功。
class ProjectActivityResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = ProjectActivity
fields = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
exclude = ('geom')
export_order = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
def hydrate_geom(self, project_activity):
print(project_activity)
return Point(float(project_activity.longitude), float(project_activity.longitude))
我用before_save_instance(self, instance, using_transactions, dry_run)
解决了
函数可以在将对象传递给模型之前对其进行修改。
class ProjectActivityResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = ProjectActivity
fields = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
exclude = ('geom')
export_order = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
def before_save_instance(self, instance, using_transactions, dry_run):
instance.geom = Point(float(instance.longitude), float(instance.latitude))
return instance
我遇到了一些问题,类似于@Nikko。我真的很难做我想做的事,而 Nikko 的代码片段帮了我大忙。我对自己所做的并不完全满意,但 它有效 并且也许它可以帮助某些人。 这很脏 所以如果有人想向我解释什么是正确的方法,我会洗耳恭听。
此代码允许您通过仅存储纬度和经度从管理界面导入和导出(使用 django-import-export)一个包含 PointField(来自 django-geojson)的 class在输出文件中(不是所有 geojson 文件)。
admin.py :
from leaflet.admin import LeafletGeoAdmin
from import_export import resources
from import_export.fields import Field
from import_export.admin import ImportExportModelAdmin
import json
from django.db import models
from djgeojson.fields import PointField
class SleepSpotResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = SleepSpot
fields = ('id','album','title','start_date','end_date','latitude','longitude' )
exclude = ('geom')
export_order = ('id','album','title','start_date','end_date','latitude','longitude' )
def before_save_instance(self, instance, using_transactions, dry_run):
longitude = float(getattr(instance, 'longitude'))
latitude = float(getattr(instance, 'latitude'))
instance.geom = {'type': 'Point', 'coordinates': [longitude, latitude]}
return instance
def dehydrate_longitude(self, sleepspot):
try:
geomjson = sleepspot.geom
if type(geomjson) is str:
geomjson = json.loads(geomjson.replace("\'", "\""))
return geomjson['coordinates'][0]
except:
pass
def dehydrate_latitude(self, sleepspot):
try:
geomjson = sleepspot.geom
if type(geomjson) is str:
geomjson = json.loads(geomjson.replace("\'", "\""))
return geomjson['coordinates'][1]
except:
pass
@admin.register(SleepSpot)
class SleepSpotModelAdmin(LeafletGeoAdmin, ImportExportModelAdmin):
list_display = ('title', 'start_date', 'end_date', 'album')
resource_class = SleepSpotResource
@Friedrich,PointField 有一个方法 coords。虽然我没有测试这个。
我会这样做:
def dehydrate_longitude(self, sleepspot):
return sleepspot.geom.coords[0]
def dehydrate_longitude(self, sleepspot):
return sleepspot.geom.coords[1]
只要保存为PointField即可:
from django.contrib.gis.geos import Point
instance.geom = Point(float(instance.longitude), float(instance.latitude))
而不是 JSON
instance.geom = {'type': 'Point', 'coordinates': [longitude, latitude]}
我正在使用 django-import-export 包来获取包含位置名称及其经纬度的 csv 文件。
我想从 csv 中解析经度和纬度字段,将它们转换为 django.contrib.gis.geos.Point
对象,以便我可以将其输入到我的 Location
模型的 geom
字段中。
# models.py
from django.contrib.gis.db import models
class Location(models.Model):
name = models.CharField(max_length=200)
geom = models.PointField(null=True, blank=True)
def __str__(self):
return self.name
# admin.py
from .models import Location
from import_export import resources
from import_export.admin import ImportExportModelAdmin
class LocationResource(resources.ModelResource):
geom = Field()
latitude = Field()
longitude = Field()
class Meta:
model = Location
fields = ('id','name', 'latitude', 'longitude')
exclude = ('geom')
export_order = ('id', 'name', 'latitude', 'longitude')
def dehydrate_geom(self, data):
return Point(data.longitude, data.longitude)
class LocationAdmin(ImportExportModelAdmin):
resource_class = LocationResource
admin.site.register(Location, LocationAdmin)
这是我取得的进展,但没有成功。 必须有:
Location(name='name', geom=Point(longitude, latitude))
CSV 文件:locations.csv
id,name,longitude,latitude
1,Naga,120.18,18.20
更新 1
尝试使用 hydrate_<field_name>
但没有成功。
class ProjectActivityResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = ProjectActivity
fields = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
exclude = ('geom')
export_order = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
def hydrate_geom(self, project_activity):
print(project_activity)
return Point(float(project_activity.longitude), float(project_activity.longitude))
我用before_save_instance(self, instance, using_transactions, dry_run)
函数可以在将对象传递给模型之前对其进行修改。
class ProjectActivityResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = ProjectActivity
fields = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
exclude = ('geom')
export_order = ('id', 'project_site', 'name', 'latitude',
'longitude', 'date_updated')
def before_save_instance(self, instance, using_transactions, dry_run):
instance.geom = Point(float(instance.longitude), float(instance.latitude))
return instance
我遇到了一些问题,类似于@Nikko。我真的很难做我想做的事,而 Nikko 的代码片段帮了我大忙。我对自己所做的并不完全满意,但 它有效 并且也许它可以帮助某些人。 这很脏 所以如果有人想向我解释什么是正确的方法,我会洗耳恭听。
此代码允许您通过仅存储纬度和经度从管理界面导入和导出(使用 django-import-export)一个包含 PointField(来自 django-geojson)的 class在输出文件中(不是所有 geojson 文件)。
admin.py :
from leaflet.admin import LeafletGeoAdmin
from import_export import resources
from import_export.fields import Field
from import_export.admin import ImportExportModelAdmin
import json
from django.db import models
from djgeojson.fields import PointField
class SleepSpotResource(resources.ModelResource):
latitude = Field(attribute='latitude', column_name='latitude')
longitude = Field(attribute='longitude', column_name='longitude')
class Meta:
model = SleepSpot
fields = ('id','album','title','start_date','end_date','latitude','longitude' )
exclude = ('geom')
export_order = ('id','album','title','start_date','end_date','latitude','longitude' )
def before_save_instance(self, instance, using_transactions, dry_run):
longitude = float(getattr(instance, 'longitude'))
latitude = float(getattr(instance, 'latitude'))
instance.geom = {'type': 'Point', 'coordinates': [longitude, latitude]}
return instance
def dehydrate_longitude(self, sleepspot):
try:
geomjson = sleepspot.geom
if type(geomjson) is str:
geomjson = json.loads(geomjson.replace("\'", "\""))
return geomjson['coordinates'][0]
except:
pass
def dehydrate_latitude(self, sleepspot):
try:
geomjson = sleepspot.geom
if type(geomjson) is str:
geomjson = json.loads(geomjson.replace("\'", "\""))
return geomjson['coordinates'][1]
except:
pass
@admin.register(SleepSpot)
class SleepSpotModelAdmin(LeafletGeoAdmin, ImportExportModelAdmin):
list_display = ('title', 'start_date', 'end_date', 'album')
resource_class = SleepSpotResource
@Friedrich,PointField 有一个方法 coords。虽然我没有测试这个。
我会这样做:
def dehydrate_longitude(self, sleepspot):
return sleepspot.geom.coords[0]
def dehydrate_longitude(self, sleepspot):
return sleepspot.geom.coords[1]
只要保存为PointField即可:
from django.contrib.gis.geos import Point
instance.geom = Point(float(instance.longitude), float(instance.latitude))
而不是 JSON
instance.geom = {'type': 'Point', 'coordinates': [longitude, latitude]}