‘RelatedFieldWidgetWrapper’ object has no attribute ‘decompress’

I just stumbled across a weird issue after upgrading to Django 1.6 from 1.5. The regression tests didn’t show any errors (you may say now that my regression tests weren’t covering everything, indeed they weren’t 🙂 ). I was just about to continue working on a feature I wanted when my admin site started to spew errors like this:

Some googling usually leads to quick solution but not today. It led me to some clue though.

So what happened? I have a specific Address field type which is based on models.ForeignKey and points to a specific model (geo.Address). In that app I have all the geographical data and logic. I might write a post later about the reasons and benefits of this but now let’s focus on why this was broken. So I have a multi input widget which used to work very nice with the necessary compress/decompress functions. But not anymore…

Googling

So I found a bug reported to Django CMS about the same problem and a workaround to put the page_link field into raw_id_fields which didn’t solve it for me obviously but pointed me to the direction where to look.

The RelatedFieldWidgetWrapper

Django wraps every ForeignKey and ManyToMany into this class so you can have the nice green plus sign next to the dropdown or multiselect so you can add related objects without leaving your form (I found this post which explains it very well: http://dashdrum.com/blog/2012/07/relatedfieldwidgetwrapper/). Somehow in Django 1.6 it’s missing the decompress function but I don’t need this wrapper anyway. My AddressField is very intelligent. It can decide if it needs to add a new row or updating an existing one.

Workaround

It’s easy I just need to override the widget in the admin, right?

No, this still doesn’t work. Django still puts RelatedFieldWidgetWrapper around your widget.

What I found to be working and it should work in any when you can miss the little green plus icon aka. you don’t need to add related objects immediately is the following.

Solution

Add this monkeypatch code to somewhere in your project which gets run every time. wsgi.py is a perfect place for example. Also you can move it out to an external file which can contain your patches.