I'm really baffled by this one:
I have 3 models, chained together by foreign keys:
from django.db import models
class A(models.Model):
name = models.CharField(max_length=100, unique=True)
class B(models.Model):
a = models.ForeignKey(A)
name = models.CharField(max_length=100, unique=True)
class C(models.Model):
b = models.ForeignKey(B)
name = models.CharField(max_length=100, unique=True)
def __init__(self, *args, **kwargs):
import pdb; pdb.set_trace()
super(C, self).__init__(*args, **kwargs)
self.name = 'inited'
When I try to get a list of all instances of C that point to a certain instance of A, C's __init__ gets called:
class SimpleTest(TestCase):
def test_goes_to_init(self):
a = A(name = 'a')
a.save()
b = B(name = 'b', a = a)
b.save()
c = C(name = 'c', b = b)
c.save()
cs = C.objects.all().filter(b__a=a)
arr = [i for i in cs] # Here C's __init__ gets called
self.assertEqual(arr.__len__(), 1)
Why should that be? Is there a way for generating the array w/o calling __init__? In my real application the __init__ function is very slow, and should be called rarely.
Here's the back trace from the debugging session:
/home/ranmoshe/sites/django/testttt/testing123/tests.py(13)test_goes_to_init()
-> arr = [i for i in cs]
/usr/local/lib/python2.6/dist-packages/django/db/models/query.py(106)_result_iter()
-> self._fill_cache()
/usr/local/lib/python2.6/dist-packages/django/db/models/query.py(760)_fill_cache()
-> self._result_cache.append(self._iter.next())
/usr/local/lib/python2.6/dist-packages/django/db/models/query.py(282)iterator()
-> obj = self.model(*row[index_start:aggregate_start])
> /home/ranmoshe/sites/django/testttt/testing123/models.py(16)__init__()
-> super(C, self).__init__(*args, **kwargs)
__init__ will be called each time the python instance is created. You are probably trying to execute the code when the database record is saved. For this, you should override your model's save() method:
class C(models.Model):
...
def save(self, *args, **kwargs):
do_something()
super(C, self).save(*args, **kwargs) # Call the "real" save() method.
do_something_else()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With