在外键连接上调用filter时调用__init__

时间:2011-07-04 07:06:23

标签: django django-models

我真的很困惑这个:

我有3个模型,用外键链接在一起:

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'

当我尝试获取指向A的某个实例的C的所有实例的列表时,C的__init__被调用:

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)

为什么会这样?有没有办法生成没有调用__init__的数组?在我的实际应用中,__init__函数非常慢,应该很少调用。

以下是调试会话的后退跟踪:

  /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)

1 个答案:

答案 0 :(得分:1)

每次创建python实例时都会调用

__init__。您可能正在尝试在保存数据库记录时执行代码。为此,您应该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()