将'QuerySet'从Django 1.4更改为1.7

时间:2015-02-02 15:50:26

标签: python django django-queryset django-1.7 django-1.4

我试图从Django 1.4.15移植应用程序 - > 1.7.3

我遇到了app在models.py

中有方法的问题
def is_votable(self, user):
        '''
        Decides if the user can vote for him/herself or not
        '''
        if self.rated_by.all().__contains__(user):
            return False
        return True

我遇到的问题就在这一行:

if self.rated_by.all().__contains__(user):

这会产生错误:

'QuerySet' object has no attribute '__contains__'

我可能会失明,因为我无法在Django中看到__contains__被弃用的地方。 非常感谢任何帮助。还可以询问您是否需要更多信息。

2 个答案:

答案 0 :(得分:3)

你几乎不应该在代码中调用像__contains__这样的双下划线方法。几乎在所有情况下,您都使用in运算符:

if user in self.rated_by.all():

请注意,这是一个Python范围的事情:例如,不是调用mylist.__length__()而是len(mylist),而不是myobj.__unicode__()执行unicode(myobj),等等。 / p>

但是,在这种特殊情况下,您可能会发现进行查询更有效:

if self.rated_by.filter(user_id=user.id).exists():

这会命中数据库以进行单个EXISTS查询。如果您没有在该特定对象的任何其他地方使用rated_by查询集,这肯定比查询all()和检查成员资格更有效。

答案 1 :(得分:1)

当查询集迭代为removed时,__contains__方法为changed,不再以块的形式创建模型。

虽然in调用__contains__方法(如果存在),但in运算符不需要存在。事实上,如果您只提供一个返回可迭代的__iter__方法,它就可以工作。由于重构不再需要任何特殊逻辑,并且__contains__是一个私有函数,因此在发行说明中没有任何特定注释将其删除。这是做Daniel所建议并且始终使用公共API的一个很好的理由,即in运算符。