'QuerySet' 从 Django 1.4 到 1.7 的变化

Change of 'QuerySet' from Django 1.4 to 1.7

我正在尝试从 Django 1.4.15 -> 1.7.3 移植应用程序

我遇到了一个问题,应用程序在 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__'

我可能是瞎子,因为我看不出 __contains__ 在 Django 中被弃用的地方。 非常感谢任何帮助。也可以询问您是否需要更多信息。

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

if user in self.rated_by.all():

请注意,这是 Python 范围内的事情:例如,您可以调用 len(mylist) 而不是调用 mylist.__length__(),而不是调用 myobj.__unicode__() 您可以调用 [=17] =],等等

不过,在这种特殊情况下,您可能还会发现执行查询更有效:

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

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

__contains__ 方法 removed when queryset iteration was changed 不再分块创建模型。

虽然 in 调用 __contains__ 方法(如果它存在),但 in 运算符不需要存在就可以工作。事实上,如果您只提供一个 returns 可迭代的 __iter__ 方法,它就可以工作。由于重构不再需要任何特殊逻辑,并且 __contains__ 是一个私有函数,因此在发行说明中没有任何具体说明的情况下将其删除。这是执行 Daniel 建议并始终使用 public API,即 in 运算符的充分理由。