Archive for the ‘django’ Category

Using django.contrib.sitemaps on AppEngine

Monday, May 17th, 2010

If you use Google AppEngine and want to use the sites and sitemaps contrib apps you can use this modified version of the google-app-engine-django helper here: http://code.google.com/p/dherbst-app-engine-django/wiki/Sitemaps

Optimize your get_or_create blocks

Tuesday, September 15th, 2009

Was going through a code review, and saw something like this:

def some_function(user_id, bobj_id):
    user = User.objects.get(id=user_id)
    bobj=Bobj.objects.get(id=bobj_id
    item, created = MyObject.objects.get_or_create(user=user, bobj=bobj)
    return item

But that is two hits to the database we don’t need since the id’s are passed in. Remember, if you have id’s then you can shortcut pulling the object from the ORM like this:

item, created = MyObject.objects.get_or_create(user__id=user_id, bobj__id=bobj_id)

That will do the

.get()

just fine, but fails when it tries to

.create()

with this error:

psycopg2.IntegrityError: null value in column “user_id” violates not-null constraint

You got the error because

get_or_create

does not automatically use the query spec for the default. There’s probably an enhancement filed for that. Remember to send in the defaults explicitly:

item, created = MyObject.objects.get_or_create(user__id=user_id, bobj__id=bobj_id,
                    defaults={'user_id':user_id, 'bobj_id':bobj_id})

Be sure you look for that in your api calls where you have mainly ids coming in and not object references.

DjangoUnicodeDecodeError gotcha!

Wednesday, January 14th, 2009

I’ve been working with international websites lately. Got this error on the Django admin pages, but no other pages on the website:

DjangoUnicodeDecodeError: Caught an exception while rendering: ‘ascii’ codec can’t decode byte … in position:6: ordinal not in range (128) ….

Went through the following steps:

1. Is my input in utf-8? Yes.
2. Is the database properly storing the right encoding? Yes.
3. Is Django pulling the data out in utf-8? Yes.

Strange, this means the data is in the right encoding, but when it is trying to display on the admin page the encoding is getting lost or coerced in to the wrong thing.

After a cup of coffee, I remembered the admin pages sometimes use the unicode() function if you don’t explicitly tell them what to display. Looked into the model code and gasped in horror:


def __unicode__(self):
return str(self.title)+u":"

Flip the str to unicode and admin pages work again.

Gotta add that to the code review list.

Soap in your eyes can be painful

Monday, August 18th, 2008

Coming from the .Net world to django and writing web services for consumers is a welcome change. .Net SOAP web services require a lot of designing and work to make them expressive yet perform well – whereas django REST services flow much more easily. However, whereas in .Net you normally throw Exceptions which turn into SoapExceptions – with django and REST I find I have to write documentation for clients/consumers explaining how to check results:

  • Success
  • Failure case 1
  • Failure case 2
  • and so on…

So, one of the painful aspects of REST is there is no predefined concept of an exception.

Another painful thing with REST I need to get used to is there is no ‘framework’ for calling REST services. Looks like an opportunity to define a common calling convention – but the drawback is I’m dictating customers/consumers use a factory-h library – because the calling conventions are well defined. If there is one thing I’ve learned – let the customer/consumer write it – guide them, but don’t write it for them. The reason being, there’s always something they want, or think they need, that I never would consider a priority.

The end result for me is that REST is quicker to write, but requires more discipline.

After kicking myself for not implementing a versioning scheme in the first .Net soap web services I designed, it’s something I started doing since. I see it over and over with the other services I’ve worked with like Amazon. I like putting the design year into the REST url: domain/2008/service-name/operation/instance

Years seem much easier, and let you know how long they’ve been baked in than version numbers.

old django newforms

Saturday, August 16th, 2008

For those of us not using django 1.0 (yet)

Newforms are great, and ModelForms will be a welcome release. However, I find I can’t utilize the over simplified workflow:

myform = MyForm(request.Post)

myform.save()

because I have to process one or more fields before saving. But there aren’t a lot of explicit examples – for some strange reason, you are required to call .is_valid() on the form before trying to access the clean_data, like this:

myform = MyForm(request.POST)

myform.is_valid() # this creates the clean_data dictionary

attribute = myform.clean_data['attributename']

Seems like the sort of thing I would code an exception into the clean_data accessor – ‘you must first call is_valid() before using’. Maybe that’s just me.