attribute: Phillie Casablanca

Category: django (18)

Changing a model

I forgot to mention this item last time, but here's what you need to do when you change a model:

From the Django FAQ:

If I make changes to a model, how do I update the database?

If you don’t mind clearing data, your project’s utility has an option to reset the SQL for a particular application: reset appname

This drops any tables associated with appname and recreates them.

If you do care about deleting data, you’ll have to execute the ALTER TABLE statements manually in your database. That’s the way we’ve always done it, because dealing with data is a very sensitive operation that we’ve wanted to avoid automating. That said, there’s some work being done to add partially automated database-upgrade functionality.

As mentioned, unfortunatly changing an existing model isn't as easy as I'd like it to be. I guess you could aways create a whole new model for any change you want made to the existing... but this still isn't the cleanest way to deal with the issue.

monkut // April 15, 2008 // 7:17 a.m.

Round Two: More notes on django

I finally got around to playing some more with django.

One, since it took me so long to come back and play I forgot my admin password... after doing some searching I finally found the answer here:

But, when I tried it from the command line I got this error, "EnvironmentError: Environment variable DJANGO_SETTINGS_MODULE is undefined.".
A quick search turned up the answer to that as well:

And Two, as you can see the text display has improved a bit.
With the help of the django filters, "urlize", and "linebreaks", returns are now converted to the proper html tags, and links can now be clicked.

I'm glad I didn't try it the hard way and manually code these features in to raw code!

See the template documentation for details:

Also, I found this site for doing django development on windows:

monkut // April 15, 2008 // 7:18 a.m.

Notes on getting django started

After following the web faction recommended screen cast and the blog easy app tutorial mentioned in the previous post I still had some issues.

1. It wasn't clear to me how to reflect changes made at first. I kept seeing the "this is your first page" page.
Resolved by: using /home/username/webapps/django/apache2/bin/stop then start

2. The admin page was not using the formatting I saw in the tutorials.
In the screen cast a similar issue was seen, and he checked the apache2/log/error.log where errors to files not found were reported. I didn't see any errors like this.

Resolved by:
I checked the file in my project and this is found:

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "", "/media/".

Ok, so media (css, JS, etc) should be in this media file, but where is this directory?

A little searching came up with the answer.

Apparently, I had to add the following to "/django/apache2/conf/httpd.conf":

This added to the LoadModule list at the top:
LoadModule alias_module /home/username/webapps/django/apache2/modules/

and this to the bottom of file:

SetHandler default

Alias /media /home/username/lib/python2.5/django/contrib/admin/media

Formatting fixed!

monkut // April 15, 2008 // 7:19 a.m.

Beyond first steps

So i've gotten more comfortable with Django.

And I've realized I now want to move beyond the initial simple blog example I initially followed.

It was a great frist step, but now to build more of a real site you need some extra features.
There are a couple of things I realized that I needed to add to the initial data model.

Mainly categories and a slug.

I first read about slugs on the django site, but didn't understand them.
Now that I wanted to link back to a historical single entry I realized that there needs to be some kind of identifier for a particular post, and slugs appear to be commonly used.

So I needed to update the model while at the same time not wanting to lose my previous notes.
Which means I apparently have to drop down into mysql and run the alter table commands myself.

This was a little daunting when I first read, "If you do care about deleting data, you’ll have to execute the ALTER TABLE statements manually in your database.". They always make it sound so easy.

Ok, so it wasn't that hard.

But, I didn't know the structure of the tables that django expects, but I remembered running across a command in the django tutorial that spat out the need sql commands to create tables, "python sql [appname]". So I ran this command and it gave me just what I needed the expected inputs for the columns I needed to add.

Next to alter the tables.

Entering mysql was easy enough, just entering 'mysql' on the command line.
But, I needed to enter the password, 'mysql -p' will gave the password prompt, then to connect to the db. (I didn't remember the password or the name of the db I created initially, luckily this is all in the file). So "connect " did the job there, then I was at the alter table add line.

And it seems to work. At least I'm not getting page errors anymore after I changed the model and ran syncdb...

Now on to the undocumented but documented commenting system:

monkut // April 15, 2008 // 7:42 a.m.

Thanks Regex Coach

I was having trouble with getting my urls to match using regex in the django

I was trying to get a single detailed post working using the generic view, "date-based object detail".

Once I got the regex right I was able to gradually debug through the rest of my issues to get it working.
I still don't fully understand the urlpatterns setting, but I understand it a little more now.

A single entry in the pattern file seems to take the following structure:
([regex for the url], [target function name to pass data to], [dictionary of additional options to pass to the function])

I'm using the ?P<name> tags in the regex, which will additionally pass the resulting information to the target function defined using the reference name in the <name> space. Other than regex itself, this part was probably what took the longest to understand.

I just want to say thanks for regex coach, I'm sure there are other similar tools out there, but I remembered this tool back when I was fighting with regex in perl. Simple but very helpful for discovering if the expression your thinking of actually matches your target text string.

(And also the webmonkey cheetsheet and special characters references I've been using these since I first started learning html back in 98 or so)

monkut // April 17, 2008 // 9:16 a.m.

And now with comments

Well I've got this up and running now with comments via django's freecomments framework.
This appears to be a very simple commenting system, so I'll probably try to move over to the main commenting framework noted here:

Wish me luck.

monkut // April 20, 2008 // 10:14 a.m.

On to the next task, feeds

Well, I briefly attempted to replace freecomments with the standard(?) more featured comments frame work, but ran into some issues. Basically, I think I'm mis-understanding something. I was hoping to add a website field so commenters could post thier websites as many sites do. However, I couldn't (quickly) figure out how to get a user identified. (when I tried to move over the user name field was removed).
If I got that working I was hoping to get openid used, so users could just login with thier yahoo or google id to add comments, or maybe add a Captcha to avoid comment spam.

Oh well, I guess basic comments should be good enough until I feel a real need otherwise.

Now on to my next tasks feeds.
Django apparently has a good feeds framework, and I expect this to go quick when I eventually dig in and look into it.

Then I guess it's really about time to decide on a name and layout. Design was always the most time consuming element for me.

monkut // May 1, 2008 // 4:01 a.m.

Notes on

I was confused for quite some time about how to get multiple generic views in a single urlpatterns definition in the file.

The examples I had been looking at would define urlpatterns something like this:


urlpatterns = patterns('django.views.generic.date_based',
{'queryset': Post.objects.all(),
'date_field': 'date',


And until today I couldn't figure out how to get multple view types in there.
The first value given to patterns seemed to restrict what views could be used.

Well I finally ran across the documentation (, and apparently that first string entry definition is the view prefix, which just means you can reduce the amount of writing if your using the same base view for all your views.

In other words if you want to use multiple views in the same urlpatterns def you just leave that first value blank:

urlpatterns = patterns('',
(r'^articles/(\d{4})/$', ''),
(r'^articles/(\d{4})/(\d{2})/$', ''),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', ''),

I'm sure its helpfull if your writting a lot of patterns, but it confused me for quite a while.
Maybe if the various examples defined this with "prefix=" I would have caught on earlier without having to dig through the documentation.

monkut // May 28, 2008 // 8:59 p.m.

How do I make category list links

I'm trying to add a sidebar of links that provides a list of categories from my posts.
The categories are dynamic so I don't want to hard code the category names.

I found what I think is a solution to the side of the issue (*maybe*) here:

Basically, the solution involves creating a wrapper function to a generic view to provide added filtering via category.

I think that does what I want to actually display the categories by date, but now to add the actual links themselves to the template.

The only thing is, now I don't see how to provide a queryset result to the template.
I see that somehow the "latest" object magically appears in my main archive template, but how do I give it a filtered query set? (At least I think that's what I want)

As I understand, latest will only give me a subset of my posts, so I won't be able to get all possible categories. Actually getting a full set of data seems wasteful, but I assume there's some kind of filter I can do on the queryset that will give me the category list. It would seem pretty trivial from an sql perspective.

Oh well, the search continues...

monkut // June 11, 2008 // 11:53 a.m.

Category link listing complete

Well, I think my category list solution has arrived.

For awhile there I thought I would have to stop using generic views and write a view to handle passing the data to the template. But actually it turned out to be pretty easy. Basically, I'm just not familar with the terms used in django, otherwise I may have figured out this earlier.

The orginal tutorial I ran through wasn't the django one so it left out some key structural explanations.
Now I think I've got it.

You define a urlpattern to handle incoming request and direct them to views. The views job is to render the template and provide a response.

The template variable is called context. Which is the part I overlooked.
Re-reading the generic views documentation I noticed that "django.views.generic.date_based.archive_index" has an optional argument, "extra_context". This option allows you to pass additional data to the template.

Then by reviewing the filtering documentation I was able to send the data I wanted to the template, and heres the added info in the file:

{'queryset': Post.objects.all(),
'date_field': 'date',


I'm understanding django more clearly now as I continue to hack away.
I don't yet feel like I'm programming yet though, it just feels like I'm configuring and tweaking settings.

monkut // June 12, 2008 // 11:33 a.m.

Syntax higlighting in posts

And an answer to my syntax highlighting question.
Now I just need the time to implement it.

I wimped out and found prettify.js here:

I initially looked at the snippets link, but was turned-off by having to do installs.
Where as with prettify I was able to accomplish what I wanted by just coping over the js and css files and adding a couple of lines to my template.

monkut // June 30, 2008 // 9:31 a.m.

Django Developer Interview

Floss weekly had a interview with Jacob Kaplan-Moss of the django development team.

It provides some nice background into django history and provides a nice intro to the general django development flow.

monkut // July 29, 2008 // 9:40 p.m.



MercurytideのDjango 1.0チートシートです:


monkut // Oct. 1, 2008 // 10:23 p.m.



monkut // Oct. 8, 2008 // 12:03 a.m.





これがDjango 1.0とGDAL 1.5.0とPROJ.4をインストールしてくれて、ENVの変数を追加してくれます。






monkut // Nov. 5, 2008 // 1:50 a.m.




(Django 1.0からのコマンドです)
まず、manage.pyまたは、django-admin.pyで: createsuperuser
Name: newadmin
Password (again):

monkut // Feb. 13, 2009 // 1:50 a.m.





class SkillCategory(models.Model):
name = models.CharField(max_length=50)

class Skill(models.Model):
category = models.ForeignKey(SkillCategory)
name = models.CharField(max_length=50)

Djangoの開発者らしいサイトから、So you want a dynamic formでの説明から、下記の答えがわかりました。


from django import forms
from myapp.models import Skill
def get_categorized_skills():
    skills = {}
    for s in Skill.objects.values('pk', 'name', 'category__name').order_by('category__name'):
        if s['category__name'] not in skills.keys():
        skills[s['category__name']] = []
        skills[s['category__name']].append((s['pk'], s['name']))
    return skills

class SkillSelectionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(SkillSelectionForm, self).__init__(*args, **kwargs)
        skills = get_categorized_skills()
        for idx, cat in enumerate(skills.keys()):
# ascii以外(日本語)の名前が使えるようにfield_name・display_nameを作成します。
field_name = u'category-%d' % (idx)
display_name = cat
            self.fields[field_name] = forms.MultipleChoiceField(choices=skills[cat],

monkut // Sept. 13, 2009 // 10:07 p.m.

Using Django 1.4 with GDAL 1.9 and PostGIS-2.0

Recently both Django 1.4 and PostGIS-2.0 were released and I needed to setup a new development environment.

However, since the release dates of both were pretty close, it looks like django-1.4 didn't manage to get support for Postgis-2.0 into the 1.4 release and the following error occures:

ERROR: operator class "gist_geometry_ops" does not accept access method "gist"

Luckily this is already identified as an issue. (See Ticket #16455 )

While the patch hasn't been accepted yet, it does appear to work for me, so at least you can use geometry columns in PostGIS-2.0 when you apply the patch.

Enable PostGIS-2.0

  1. Install Postgres 9.1 then install PostGIS-2.0

  2. Apply the patch to django.contrib.gis.db.backends.postgis.creation described in Ticket #16455

  3. Check/Set the GDAL_DATA environment variable is set to C:\Program Files (x86)\PostgreSQL\9.1\gdal-data

  4. Check/Set the PROJ_LIB environment variable is set to C:\Program Files (x86)\PostgreSQL\9.1\share\contrib\postgis\proj

  5. Check/Set the PROJ_SO environment variable is set to C:\Program Files (x86)\PostgreSQL\9.1\bin\libproj-0.dll


The gdal-data folder is ONLY installed with postgis-2.0, and is not found in postgis-1.5.
This folder is needed to perform projection translations and the python GDAL library also needs this information.

Once this is done you should be able to create/syncdb for models that contain geometry fields.

Enable GDAL-1.9.0:

Almost every time I setup or someone in my team sets up a new development environment someone has an issue getting GDAL to work. In my case I need some of the raster features available in the stock gdal package which are NOT available in the django version (see note). So I nned to install the standard python GDAL package in pypi.

Getting this to work with django was a long process of trial and error. Here's what I did (on win7):

  1. Install GDAL-1.9

  2. Next, create the directory C:\gdallibs.

  3. Then copy all the DLLs that were installed in C:\Python27\Lib\site-packages\osgeo to C:\gdallibs

  4. Add C:\gdallibs to the PATH environment variable.

    • Once added to your PATH django should find the libraries.

  5. django-1.4 does not yet have support for gdal-1.9.0 and cannot find the 1.9 library. Overwrite the local django.contrib.gis.gdal.libgdal with this updated version

    • This adds gdal1.9 to the library search and also allows configuration of GDAL_LIBRARY_PATH as an environment variable. (Although, I found it was not needed once C:\gdallibs was created and added to the PATH.

  6. Confirm that gdal.HAS_GDAL+ and *gdal.GEOJSON are True:

    >>> from django.contrib.gis import gdal
    >>> gdal.HAS_GDAL
    >>> gdal.GEOJSON


You may need to open a NEW console for the updated PATH environment variable to take effect.

monkut // May 2, 2012 // 4:45 p.m.