【问题标题】:Change of 'QuerySet' from Django 1.4 to 1.7将 'QuerySet' 从 Django 1.4 更改为 1.7
【发布时间】:2015-02-02 15:50:26
【问题描述】:

我正在尝试从 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 中被弃用的地方。 任何帮助都深表感谢。也请询问您是否需要更多信息。

【问题讨论】:

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


    【解决方案1】:

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

    if user in self.rated_by.all():
    

    请注意,这是 Python 范围内的事情:例如,不是调用 mylist.__length__(),而是调用 len(mylist),而不是调用 myobj.__unicode__(),而是调用 unicode(myobj),等等。

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

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

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

    【讨论】:

    • 感谢您的帮助。也解释了很多。非常感谢您的回答。
    • 不要忘记接受答案,向未来的搜索者表明它解决了问题。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 2014-11-25
      • 2014-12-10
      • 2012-05-20
      • 1970-01-01
      • 2017-12-12
      • 2014-09-14
      相关资源
      最近更新 更多