Jun 04 2008
GeoDjango on Slicehost: Creating a GeoDjango Project (4 of 4)
This final post goes over how to create a test GeoDjango project.
Creating a Website Directory Structure
Create a location for the website directory structures.
mkdir ~/website
Create a directory structure for the test_geodjango.slicename.com website.
mkdir -p ~/website/test_geodjango.slicename.com/{public,private,log,cgi-bin,backup}
Create a GeoDjango Project
Create a default Django project…
cd ~/website/test_geodjango.slicename.com/public django-admin.py startproject test_geodjango
Add the GDAL library path to the Django project settings…
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/settings.py
Add the following line so your Django project can found the GDAL library…
GDAL_LIBRARY_PATH = '/usr/local/lib/libgdal.so'
Test out the project (using the internal web server)…
python ~/website/test_geodjango.slicename.com/public/test_geodjango/manage.py runserver 8001
You should see a response like the following…
Validating models... 0 errors found Django version 0.97-pre-SVN-7547, using settings 'test_geodjango.settings' Development server is running at http://127.0.0.1:8001/ Quit the server with CONTROL-C.
Even though the server is running, you would be able to see a Django page since port 8001 is not open. Quit the server for now…
Create a new view
Create a new view file for the project…
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/views.py
and insert the following code
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "It is now %s." % now
return HttpResponse(html)
Edit the URL configuration file
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/urls.py
Replace the content with the following code which will be used to display a Django test page…
from django.conf.urls.defaults import *
from test_geodjango.views import current_datetime
urlpatterns = patterns('',
(r'^time/$', current_datetime),
)
Configure Apache to recognize the new virtual host
sudo nano /etc/apache2/sites-available/test_geodjango.slicename.com
Add the following to configure the virtual host
# Place any notes or comments you have here
# It will make any customization easier to understand in the weeks to come
# domain: test_geodjango.domain.com
# public: /home/demo/website/test_geodjango.domain.com/
<VirtualHost *>
# Admin email, Server Name (domain name) and any aliases
ServerAdmin webmaster@slicename.com
ServerName test_geodjango.slicename.com
# Index file and Document Root (where the public files are located)
#DirectoryIndex index.html
DocumentRoot /home/demo/website/test_geodjango.slicename.com/public
<Directory "/">
Order deny,allow
Allow from all
</Directory>
<Location "/">
SetHandler python-program
PythonPath "['/home/demo/website/test_geodjango.slicename.com/public'] + sys.path"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE test_geodjango.settings
PythonDebug On
</Location>
# Custom log file locations
LogLevel warn
ErrorLog /home/demo/website/test_geodjango.slicename.com/log/error.log
CustomLog /home/demo/website/test_geodjango.slicename.com/log/access.log combined
</VirtualHost>
Enable the site and reload apache to use the new configuration…
sudo a2ensite test_geodjango.slicename.com sudo /etc/init.d/apache2 reload sudo apache2ctl graceful
On your local computer, edit the /etc/hosts file and add the following line to setup an override
11.222.333.444 test_geodjango.slicename.com
Test it out, by opening up a Web browser and go to http://test_geodjango.slicename.com/time/ You should see a page that shows something like…
It is now 2008-05-24 11:22:33.991752.
Create a PostGIS database
Next we will create a PostGIS database for the project… (I have included the shell prompts to make it more clear what user/context is running the command.)
myslice ~: sudo su - postgres postgres@myslice:~$ createuser -SDRP testuser postgres@myslice:~$ createdb -O testuser test_geodjango_db postgres@myslice:~$ createlang plpgsql test_geodjango_db postgres@myslice:~$ psql -d test_geodjango_db -f /usr/share/lwpostgis.sql postgres@myslice:~$ psql -d test_geodjango_db -f /usr/share/spatial_ref_sys.sql postgres@myslice:~$ psql test_geodjango_db test_geodjango_db=# ALTER TABLE geometry_columns OWNER TO testuser; test_geodjango_db=# ALTER TABLE spatial_ref_sys OWNER TO testuser; test_geodjango_db=# \q postgres@myslice:~$ exit myslice ~:
Configure the Django database configuration
(reference: http://www.djangobook.com/en/1.0/chapter05/)
Edit the settings file for the Django project…
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/settings.py
And update the database connection parameters
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME = 'test_geodjango_db'
DATABASE_USER = 'testuser'
DATABASE_PASSWORD = 'password'
DATABASE_HOST = ''
DATABASE_PORT = ''
Test the database connection
Open up a Python shell for the project…
cd ~/website/test_geodjango.slicename.com/public/test_geodjango python manage.py shell
Python 2.5.2 (r252:60911, Apr 21 2008, 11:17:30)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
(InteractiveConsole)
>>>
>>> from django.db import connection >>> cursor = connection.cursor() >>>
If the cursor = connection.cursor() command did not produce any response, then the database connection was successfully made.
Add a Django App and Define a Model
(see http://www.djangobook.com/en/1.0/chapter05/ and http://code.djangoproject.com/wiki/GeoDjango)
Create a Django application and edit the model configuration file…
python manage.py startapp testapp nano testapp/models.py
And replace with the following…
from django.contrib.gis.db import models
class District(models.Model):
name = models.CharField(max_length=35)
num = models.IntegerField()
poly = models.PolygonField()
objects = models.GeoManager()
class School(models.Model):
name = models.CharField(max_length=35)
point = models.PointField()
objects = models.GeoManager()
Install the Django App
Edit the settings configuration file…
nano settings.py
and edit the INSTALLED_APPS section as follows
INSTALLED_APPS = (
#'django.contrib.auth',
#'django.contrib.contenttypes',
#'django.contrib.sessions',
#'django.contrib.sites',
'test_geodjango.testapp',
)
Sync the database with the Django model…
python manage.py syncdb
which should produce the following…
Creating table testapp_school
Creating table testapp_district
Installing custom SQL for testapp.School model
Installing custom SQL for testapp.District model
Test access to the database from the command line…
python manage.py shell >>> from testapp.models import District, School >>> d1 = District(name='Test District 1' , num=1, poly='POLYGON((-96 29,-95 29,-95 30,-96 29))' ) >>> d1.save() >>> qs1 = District.objects.filter(poly__bbcontains='POINT(-95.362293 29.756539)') >>> qs1
Python should echo back a District object. This returns an array with a single district record, since the district polygon’s bounding box contains the point.
[<District: District object>]
Try again a query that does not return any points (since the point is not contained within the district polygon)…
>>> qs2 = District.objects.filter(poly__contains='POINT(-95.362293 29.756539)') >>> qs2
[]
Displaying GeoDjango Results on a Web Page
Create another view file for the project…
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/testapp/views.py
and add a view that returns the results of a GeoDjango query…
from django.http import HttpResponse
import datetime
from models import District, School
def test_geodjango_view(request):
now = datetime.datetime.now()
pointWkt = 'POINT(-95.362293 29.056539)'
districtSet = District.objects.filter(poly__contains=pointWkt)
html = "It is now %s." % now
html += "<br/><br/>"
if len(districtSet)>0:
for district in districtSet:
html += "%s is in %s" % (pointWkt, district.name)
else:
html += "%s is not within any districts" % pointWkt
return HttpResponse(html)
Update the URL configuration…
nano ~/website/test_geodjango.slicename.com/public/test_geodjango/urls.py
to match the following…
from django.conf.urls.defaults import *
from test_geodjango.views import current_datetime
from test_geodjango.testapp.views import test_geodjango_view
urlpatterns = patterns('',
(r'^time/$', current_datetime),
(r'^test/$', test_geodjango_view),
)
Reload the Apache configuration…
sudo /etc/init.d/apache2 reload sudo apache2ctl graceful
If you get a message saying that httpd is not running, try reloading the Apache configuration again…
sudo /etc/init.d/apache2 reload sudo apache2ctl graceful
Test out the web page…
Point a browser at: http://test_geodjango.slicename.com/test/
You should see something similar to
It is now 2008-06-04 21:26:17.022444.
POINT(-95.362293 29.056539) is in Test District 1
if that works, you now have a working (although trivial) GeoDjango website served via Apache. Now its up to you to make do something interesting. Good luck…
Leave a Reply
You must be logged in to post a comment.