overriding saving fails in loop

478 views
Skip to first unread message

Ali Rıza Keleş

unread,
Mar 10, 2010, 3:32:55 PM3/10/10
to django...@googlegroups.com
Hi all,

I want to override saving of one of my models.
After saving any record, I am trying to reorder them all.

class Subject(models.Model):
slug = models.SlugField(db_index=True, unique=True)
name = models.CharField(max_length="120")
order = models.CharField(blank = True, max_length="3")

class Meta:
ordering = ['order']

def __unicode__(self):
return u'%s' % (self.name)

def __str__(self):
return self.__unicode__()

def save(self, *args, **kwargs):
super(Subject, self).save(*args, **kwargs)
self.makeOrder()

def makeOrder(self):
t = 10
for i in Subject.objects.all().order_by('order'):
i.order = t
i.save()
t += 10


But here, It fails in a loop and give "maximum recursion depth exceeded"
error.

How can I do?

Thanks..

--
Ali


Shawn Milochik

unread,
Mar 10, 2010, 3:37:42 PM3/10/10
to django...@googlegroups.com
Every time you save(), you call makeOrder(). Every time you run makeOrder(), you call save(). You've introduced an infinite loop. Well, infinite until Python decides enough is enough.

One simple possibility is to add an optional argument with a default of True to the save() override that determines whether to makeOrder(). Just ensure that when makeOrder() calls save() that it sets that to False.

Shawn


Beres Botond

unread,
Mar 10, 2010, 4:46:01 PM3/10/10
to Django users
Even if we ignore the infinite loop, selecting and updating every
single instance of Subject at every save() of a Subject, is horribly
wrong and inefficient on many levels.

Exactly what kind of functionality/logic were you trying to implement?

Beres Botond

unread,
Mar 10, 2010, 4:49:26 PM3/10/10
to Django users
Or more specifically, why exactly do you want to reorder them all at
every Subject .save()? And what exactly do you use the values in
'order' field for?

Ali Rıza Keleş

unread,
Mar 10, 2010, 5:18:05 PM3/10/10
to django...@googlegroups.com
El mié, 10-03-2010 a las 15:37 -0500, Shawn Milochik escribió:
> Every time you save(), you call makeOrder(). Every time you run
> makeOrder(), you call save(). You've introduced an infinite loop.
> Well, infinite until Python decides enough is enough.
>
Yes right.

But I need to reorder them all after each saving. If I try to reorder
while saving, It starts a new saving, ... and so on.. that means
infinitive loop.


> One simple possibility is to add an optional argument with a default
> of True to the save() override that determines whether to makeOrder().
> Just ensure that when makeOrder() calls save() that it sets that to
> False.

sorry. I couldn't do anything. makeOrder calls save for each item.

an example:
let them be first states of records.

name order
-----------------
a 10
b 20
c 30
d 40
e 50

for example when I changed 'c' to 45, because I want to insert 'c'
between 'd' and 'e'

First of all c would be set to 45,

name order
-----------------
a 10
b 20
c 45
d 40
e 50

after reordering them 10 intervals, 'd' would be set 30 and 'c' would be
set 40. So now 'c' is between 'd' and 'e' as I expected.

name order
------------------
a 10
b 20
c 40
d 30
e 50

How can I do this?

Thanks.

--
Ali

> Shawn

Shawn Milochik

unread,
Mar 10, 2010, 5:28:40 PM3/10/10
to django...@googlegroups.com
I think you missed my point, or I explained it badly.

1. In makeOrder, change i.save() to i.save(reorder = False).

2. Change the save function to something like the following (untested):

def save(self, *args, **kwargs):

do_ordering = kwargs.pop('reorder', True)

super(Subject, self).save(*args, **kwargs)

if do_ordering:
self.makeOrder()


This way, the makeOrder function will be called every time an instance is saved, *except* what that save was called from the makeOrder function. This is exactly what you're asking for.

Shawn

Ali Rıza Keleş

unread,
Mar 10, 2010, 5:42:03 PM3/10/10
to django...@googlegroups.com

Hımm.. That's the point. Perfecto..
Gracias Shawn..

I am learning...

Thanks..

--
Ali Rıza


Reply all
Reply to author
Forward
0 new messages