Overriding model __init__() method

2,416 views
Skip to first unread message

Nathaniel Whiteinge

unread,
Apr 28, 2008, 8:20:10 PM4/28/08
to Django users
I'm using the __init__() method in a few models to save state for
later use in save(), e.g.::

class MyModel(models.Model):
...
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)
self.old_value = self.value
def save(self):
if self.old_value != self.value:
...
super(MyModel, self).save()

But that functionality seems to have broken in the last week. It
appears that __init__() isn't be called (as often?) as it used to. I'm
on the GIS branch and it seems to have broken on r7482 (qs-rf merge).

I'm on deadline this week, and don't have much time to play with a
small test app on trunk, but I use this technique in other projects,
so I was wondering if this method an ok way to check for changes
between model saves and there's a bug somewhere, or am I doing
something fragile that should be done another way?

- whiteinge

Malcolm Tredinnick

unread,
Apr 28, 2008, 9:03:52 PM4/28/08
to django...@googlegroups.com

On Mon, 2008-04-28 at 17:20 -0700, Nathaniel Whiteinge wrote:
> I'm using the __init__() method in a few models to save state for
> later use in save(), e.g.::
>
> class MyModel(models.Model):
> ...
> def __init__(self, *args, **kwargs):
> super(MyModel, self).__init__(*args, **kwargs)
> self.old_value = self.value
> def save(self):
> if self.old_value != self.value:
> ...
> super(MyModel, self).save()
>
> But that functionality seems to have broken in the last week. It
> appears that __init__() isn't be called (as often?) as it used to. I'm
> on the GIS branch and it seems to have broken on r7482 (qs-rf merge).

Can you open a ticket for this please? I need to think about it a bit
because it might be fiddly to fix.

The underlying issue is that object initialisation has changed and I
didn't think of this sort of situation (overriding __init__ was fragile
in the distant past; not so much in recent times). What's now going on
is that there's a "fast" creation method of models that is used when
initialising them from a sequence of arguments -- primarily for database
creation. That's the from_sequence() method on the Model class. Because
that's a class constructor, it doesn't also call __init__() -- it
replaces __init__.

So, like I said, I should think about some alternative approaches here.
We kind of need the fast path for code robustness and speed (it can
throw away a bunch of error checking in that path because it's not
intended for general public use), but I don't want to break normal
Python practices either. Open a ticket and I'll put some effort in.

Regards,
Malcolm

--
Honk if you love peace and quiet.
http://www.pointy-stick.com/blog/

Reply all
Reply to author
Forward
0 new messages