Related Plugins and Tags

QGIS Planet

Installing python GDAL into a python virtualenv in OSX

Yes I know its a bit wierd to see the word ‘OSX’ in an article by me…I recently bought a Mac for testing InaSAFE and fooling around with FOSSGIS software on OSX. Besides the 2 or three days it took to get it set up as a development machine for FOSSGIS stuff (as compared to... Read more »

Django : Faking it with South

So we use the super awesome South to manage schema changes when we change our django models. Basically South works in the background to make sure that your database is always in a consistent state with your models. Recently I have been adding South to a project and deploying these updates to my server. One [...]

Django development with Eclipse and PyDev

Eclipse is a Java IDE right? Wrong! You can use it for other languages too! I have been needing to improve my debugging techniques for python and Django (more on that in the future). This post outlines how you can set up Eclipse with PyDev to work on an existing Django aplication. The benifits? A [...]

How to move a django project and its virtual environment

We do a lot of django work here at Linfiniti and always use a python virtual environment with each project so that the runtime requirements are isolated to that project. Our typical project looks like this:   projectfolder +-- django_project    +-- django_app +-- python    +-- bin    +-- include    +-- lib    [...]

Django: serving an image from a remote server

For a current project (using django), I wanted to get a dynamically generated image from a remote map server and return the image to the django view as an object (as opposed to returning a URL as a string).

Here's how it's done (logic derived from this code snippet):

import urllib
import urllib2
import mimetypes

def serveMapImage( theArea ):
  # omitted: procedure to define the variable zoomExtents
  # from user-specified, database-derived variable theArea
  URI = "http://example.com/mapofsouthafrica-" + zoomExtents
  contents = urllib2.urlopen(URI).read()
  mimetype = mimetypes.guess_type(URI)
  response = HttpResponse(contents, mimetype=mimetype)

  return response
pixelstats trackingpixel

Listing the number of records in all postgresql tables

I love bash and the gnu tools provided on a Linux system. I am always writing little oneliners that help me do my work. Today I was generating some fixtures for django (yes I am finally properly learning to use unit testing in django). I wanted to know how many records where in each table in my database. Here is the little one liner I came up with:

 

for TABLE in $(psql foo-test -c "\dt" | awk '{print $3}'); do \
psql foo-test -c "select '$TABLE', count(*) from $TABLE;" | grep -A1 "\-\-\-\-" | tail -1; done

 

It produces output that looks something like this:

auth_group |     0
auth_group_permissions |     0
auth_message |     0
auth_permission |   273
auth_user |   366
auth_user_groups |     0
auth_user_user_permissions |     0
etc.

 

 

 

pixelstats trackingpixel

Help wanted: FOSS GIS and Python Geek in Africa

Are you a python programmer adept at django and other technologies in the web mapper’s toolbox? We have an exciting project on the go and are looking for someone to help us during the months of February and March 2011. You can work remotely if needed, or here in Swellendam, Western Cape, South Africa if you prefer. Please note applicants must already be available full time for these months (or a good part of them) and already up to speed with these technologies – there will be no time for ‘learning on the job’. Please send me your CV to tim [A T] linfiniti.com if you are interested.

Hope to hear from you soon!

Tim

pixelstats trackingpixel

Bending django flatpages to your will

I’ve been working on a web site for a client that uses django flatpages. Flatpages is a built in component that allows users to create static content within the admin interface and publish it to the web front end. Think of it as a basic content management system component for django. Out of the box django’s flatpages have some limitations though – you cannot easily dictate a sort order or heirachy for the pages. Let me demonstrate…

The old way:

Typically one might show a list of your flatpages on your website you would do something like this

{% load flatpages %} {# Custom tag defined in lib/templatetags/ #}
{% get_flatpages as flatpages %}
<ul>
{% for page in flatpages %}
 <li><a href="{{ page.url }}">{{ page.title }}</a></li>
{% endfor %}
</ul>

Which might generate some html rendered out like this:

Basic flat page listing

Basic flat page listing

Extending the FlatPages model:

We can use model inheritance to add a couple of fields to the flatpages model as explained here. To do that I simply add something like this to my models.py:

from django.db import models
from django.contrib.flatpages.models import FlatPage
class ExtendedFlatPage(FlatPage):
 show_after = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_predecessor", \
   help_text="Page that this one should appear after (if any)")
 child_of = models.ForeignKey('ExtendedFlatPage', \
   null=True, blank=True, default=None, \
   related_name="flatpage_parent", \
   help_text="Page that shis one should appear under (if any)")

So my new model adds two fields to the flatpages model that will allow me to define ordering and heirachy. The show_after field means that when I create a new flatpage, I can specify which other page the new page should be shown after. The child_of field can be used to state that the new page being added is a child of another page. A quick run of

python manage.py syncdb

Will go ahead and create the new table for your extended flat pages model. If we want to migrate existing flatpages into the new model, you can run a little query from the postgres command prompt like this:

insert into localsite_extendedflatpage (flatpage_ptr_id)
  select (id) from django_flatpage;

Where localsite_extendedflatpage is the table that was generated for your model (its name will vary depending on the name of your django app).

Registering the model in the admin interface:

To allow the user to administer the extended flat pages, you need to register your custom flatpages model with the admin interface and deregister the existing one (in admin.py):

from django.contrib import admin
from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
from django.contrib.flatpages.models import FlatPage

from models import ExtendedFlatPage

class ExtendedFlatPageForm(FlatpageForm):
 class Meta:
   model = ExtendedFlatPage
class ExtendedFlatPageAdmin(FlatPageAdmin):
 form = ExtendedFlatPageForm
 fieldsets = (
 (None, {'fields': ('url', 'title', 'content', \
         'sites', 'show_after', 'child_of' )}),
 )
admin.site.unregister(FlatPage)
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin)

After restarting your web server, you should now see the ExtendedFlatPages model listed in your admin interface, and it should show you our two custom fields which we use to define order and heirachy.

Admin interface for our customised flatpages model

Admin interface for our customised flatpages model

Creating a custom template tag:

The next step in our journey is to create a custom templatetag that will render our listing of flatpages according to their heirachy and order. I added this to <myapp>/templatetags/local_tags.py :

from django import template
from localsite.models import ExtendedFlatPage
register = template.Library()
@register.simple_tag
def show_ordered_flatpages():
 flatPages = ExtendedFlatPage.objects.filter(child_of__isnull=True).order_by('-show_after')
 myString = ""
 for myPage in flatPages:
   myString += get_ul_for_page( myPage )
 return myString

def get_ul_for_page( thePage ):
 flatPages = ExtendedFlatPage.objects.filter(child_of=thePage).order_by('show_after')
 if len(flatPages) < 1:
   return """<li><a href="%s">%s</a></li>""" % ( thePage.url, thePage.title )
 else:
  myString = """<li><a href="%s">%s</a>""" % ( thePage.url, thePage.title )
  myString += "<ul>\n"
  for myPage in flatPages:
    myString += get_ul_for_page( myPage ) #recursion
  myString += "</ul>\n"
  myString += "</li>\n"
  return myString

So the template tag uses a simple recursive function to generate a heirachical nested collection of unordered lists (ul). The last thing I need to do is update my template that shows a listing of available flatpages to look something like this:

{% load local_tags %}

<div class = "flat-page-list">
   {% show_ordered_flatpages %}
</div>

The result:

After making the above changes, my contrived list of flatpages now looks like this when rendered:

Flatpages rendered using user defined order and nesting

Flatpages rendered using user defined order and nesting

A couple of gotchas:

My examples above do not check to see where the logged in user has the rights to view a page. Also my ExtendedFlatPages model needs to have some checks added to ensure that show_after and child_of fields can not be populated with a reference back to themselves (which would probably cause infinite recursion in my templatetag code).

pixelstats trackingpixel

GeoDjango 3 Day Course

This week I conducted a 3 Day GeoDjango course. We had 11 particpants consisting of SITA (South African State Information Technology Agency) employees and interns, and other non-SITA employees. The course was given free in order to promote skills development in Open Source GIS, and the lab facilities were donated by SITA, Perseus Park, Pretoria, South Africa.

It was really great to meet the attendees and I hope the course sowed a seed of interested in them that will prompt them to go off and make beautiful open source web sites powered by GeoDjango!

GeoDjango 3 day course 7-9 Dec 2009

GeoDjango Tutorial

A while ago I posted a story about a GeoDjango training course I have been creating. By popular demand here are the course notes I made. Hope they are useful and I will appreciate any suggestions folks can offer to improve them.

  • Page 1 of 1 ( 10 posts )
  • geodjango

Back to Top

Sustaining Members