Optional GIS field in a model

92 views
Skip to first unread message

Aapo Rista

unread,
Dec 6, 2012, 12:10:36 PM12/6/12
to django...@googlegroups.com
I've a generic app for saving files, usually photos and videos, but also audio files, PDFs and some other binaries are supported. I've a model called Content, which stores the file and some metadata, including GeoDjango's PointField for GPS coordinates. I'm using PostgreSQL and PostGIS 1.5. I think the most important parts of my models.py are here:

from django.contrib.gis.db import models

class Content(models.Model):
    file = models.FileField()
    point = models.PointField(geography=True, blank=True, null=True)
    objects = models.GeoManager()

Now I've found out that this Content model would be useful (because it contains lots of logic related to e.g. saving files) even without this GIS part. Installing all GIS libraries etc. may be challenging sometimes in some environments and if someone just wants to quickly test this app, I'd like to make this PointField and GeoManager optional, so user could use SQLite3 (without a need to install any external DBMS). Actually PointField's coordinates are in most cases only used to show the file on the map in this Content app, so FloatFields for lat and long would be enough in most cases. BUT there are also some advanced features (e.g. find nearest neighbors) which rely on GIS, so I don't want to completely move this PointField out from Content model.

Basically I want to do this:
if GIS_DATABASE is True:
    add PointField and GeoManager to Content model
else:
    add lat and long FloatFields

Any clue how to do this without any horrible kludges? I've tried to put 'ENGINE': 'django.db.backends.sqlite3' into my settings.DATABASES and then something like this:

class Content(models.Model):
    try:
        point = models.PointField(geography=True, blank=True, null=True)
        objects = models.GeoManager()
    except Exception, err:
        print "IN MODEL", err

But running

$ python manage.py syncdb

just yields

Creating tables ...
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'


Nikolas Stevenson-Molnar

unread,
Dec 6, 2012, 4:32:35 PM12/6/12
to django...@googlegroups.com
The reason for your syncdb error is that the table creation doesn't happen as part of the class definition (in other words, there's no error in creating your Content class).

Why not add an "ENABLE_GIS" setting to your settings file? Then use your if/else:

from django.conf import settings
...

ENABLE_GIS = getattr(settings, 'ENABLE_GIS', False) #GIS disabled by default

class Content:
        ...
        if ENABLE_GIS:
                <gis fields here>
        else:
                <plain fields here>

_Nik
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/_8AZ-ZYAZhkJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Aapo Rista

unread,
Dec 6, 2012, 5:31:32 PM12/6/12
to django...@googlegroups.com
On Thursday, December 6, 2012 11:32:35 PM UTC+2, Nikolas Stevenson-Molnar wrote:
The reason for your syncdb error is that the table creation doesn't happen as part of the class definition (in other words, there's no error in creating your Content class). Why not add an "ENABLE_GIS" setting to your settings file? Then use your if/else:

class Content:
        ...
        if ENABLE_GIS:
                <gis fields here>
        else:
                <plain fields here>

Initially this seems to work, so thank you for this idea! I'll be very happy if the solution will be this simple. :)
I've to do some refactoring and testing now, let's see if this is the solution.

-- 
Aapo

Reply all
Reply to author
Forward
0 new messages