又遇到了灵异事件。。Django的ORM。orz.
昨天对Blog的程序进行了优化。见前一篇文章, 因于文章分类允许为Null导致查询文章列表时(列表需要显示分类名)Select_related不起作用引发了1+N问题,所以我把Null= True去掉。减却了多余的N条查询。但是奇怪的事情发生了,我从早上开始发觉,首页列表的作者变成了Blog的Title。但代码明明是 {{entry.author.name}}!我改成其他属性试下,依然是Print出Blog的其他属性。我回想昨天更新做过的改动,撒销均无效。最后 想起会不会是因为改了Model的属性引起的,于是我把分类的Null=True加上。果然!显示正常了。这是为什么呢?不解!缓存?没可能吧?
我是不可能再把分类的Null=true保留的,因为实践证明这样对性能损耗太大。但不加上又出现属性值错乱的情况。怎么办?最后我作了个尝试,我把Model里面的属性调换了一下位置,原来Author在Catelog下方:
catelog = models.ForeignKey(Catelog,verbose_name='分类')
author = models.ForeignKey(Account,verbose_name='作者')
现在改回来,Author写在Catelog上方。显示正常。My god!
author = models.ForeignKey(Account,verbose_name='作者')
catelog = models.ForeignKey(Catelog,verbose_name='分类')
这是我的程序的Bug?还是Django的Bug?还是我的Bug?我想这个解决的办法不是好办法。
我拿到三种情况的Sql。一是分类为Null的查询,二是分类为NotNull的查询,三是分类为NotNull且Author属性排在 Catelog前面的查询。结果是第一和第三种情况blog_account_name所在的列位置是一样的。这是否说明Django的确是记住查询结果 的位置并且缓存起来了?但缓存到哪里了呢?如果刷新呢?
原因追寻中。原文见:http://www.fallever.com/blog/jeff/17/