[Solved]-Parsing fields in django-import-export before importing

15πŸ‘

βœ…

It was resolved when I used before_save_instance(self, instance, using_transactions, dry_run)

The function can modify the object before passing it to the model.

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

1πŸ‘

I had some problem, similar to @Nikko. I had a really hard time doing what I wanted, and Nikko pieces of code helped. I’m not completely satisfied with what I’ve done but it works and maybe it can help some people. It’s dirty so if someone wants to explain me what would be the right way, I’m all ears.

This code allows you to import AND export (using django-import-export), from the admin interface, a class containing a PointField (from django-geojson) by storing only the latitude and the longitude in the output file (not the all geojson file).

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
πŸ‘€Fritzip

0πŸ‘

@Friedrich, a PointField has a method coords. I did not test this though.

I would do this:

def dehydrate_longitude(self, sleepspot):
    return sleepspot.geom.coords[0]

def dehydrate_longitude(self, sleepspot):
    return sleepspot.geom.coords[1]

as long as it is saved as PointField:

from django.contrib.gis.geos import Point
instance.geom = Point(float(instance.longitude), float(instance.latitude))

instead of a JSON

instance.geom = {'type': 'Point', 'coordinates': [longitude, latitude]}

πŸ‘€Nikko

Leave a comment