Category Archives: Django

Python – comparing floats and decimals

No matter how old I get, I keep being bitten by the joys of having some data as floats and some as decimals.

ipdb> value
ipdb> from_value
ipdb> value < from_value

because …

ipdb> from decimal import *
ipdb> Decimal(from_value)

So work out what accuracy you need and do something like

from_value = Decimal(from_value).quantize(Decimal('0.0001'))

Staticfiles in Django 1.3 not working?

Wasted a lot of time on this today when I shouldn’t have done.

If you find that your staticfiles in Django are just not working for you, when the docs say they should be, try this. The docs say here that:

“This view is automatically enabled and will serve your static files at STATIC_URL when you use the built-in runserver management command.”

Well, it doesn’t work for me. As per the example after I had to amend my specifically – i.e.:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... the rest of your URLconf goes here ...

urlpatterns += staticfiles_urlpatterns()

If anyone knows whether this is a bug or just me please tell me.

Django/Postgresql – inserting new record doesn’t return id.

You have an old database and you find the following happens.

>>> ap = ValidAirPressureCode(code='9', description='9', barcode='9', comments='
>>> ap = ValidAirPressureCode.objects.get(code='9')

In short Django doesn’t return the id of a newly inserted record. If you insert records in admin and choose to continue editing, you’ll get an error saying it can’t find a record with a null id. The problem (in my case) is that Django uses a postgres function called “pg_get_serial_sequence” to identify where the last inserted number given to a table’s record is stored but if your tables were not created using the serial type, this will return null. In my case it was because the database was nine years old and serial types did not exist then.

A proposed solution can be seen on this ticket but at the time of writing it is not implemented.

To fix it in my case I took a look at what my sequences were called. For example:

id | integer| \
    not null default \

. I then wrote the following piece of middleware (just inserted a call to it in my middleware section).

class FixLastInsertId(object):

    def __init__(self):
        """ """
        def my_last_insert_id(self, cursor, table_name, pk_name):
            """ This code fails on the alc database, so we fall back to a method of
            getting the last id that does work"""

            sql = "SELECT CURRVAL(pg_get_serial_sequence('%s','%s'))" % (self.quote_name(table_name), pk_name)
            result = cursor.fetchone()[0]
            if not result:
                sql = "select currval('%s_pk_seq'::regclass)" % table_name
                result = cursor.fetchone()[0]
            return result

        from django.db import connection
        connection.ops.__class__.last_insert_id = my_last_insert_id

        # Tell Django to forget about this middleware now, we have
        # had our evil way.
        from django.core.exceptions import MiddlewareNotUsed
        raise MiddlewareNotUsed

Basically I monkey patch the last_insert_id method. I call the normal code and if that fails try with my own way. All my sequences have the same naming convention (tablename_pk_seq) so it works for me.

Thanks to Ross for pointing me in the right direction, although he didn’t approve of my monkey patching solution 😉

Converting Legacy Databases to Django 1.3 – Day 0.5

I have done this quite a few times in the past, but not recently. I was given three days to convert an existing postgres database (front ended with Zope) to Django 1.3. I thought it would be useful to document what I did here for my own future reference and to record any gotchas for posterity. The database I am converting is nine years old, so plenty of cruft through the years, although the basic structure is sound.

Note that the website of this application is not particularly complicated. Most of the core work of this application is done via backend processes written with Twisted. The front end is used for displaying the system status and allowing for data to be modified, with a few additional complications. The system will work without any web front end (although this is hardly ideal) without stopping production, so the risk is minimised.

This is the first day – although I only started from the beginning of the afternoon, so it’s the first half a day.
Continue reading