Python Django queryset中的Bug与count?

Python Django queryset中的Bug与count?,python,django,django-queryset,django-1.5,Python,Django,Django Queryset,Django 1.5,你可以猜到我有一个非常奇怪的问题。 我有一个queryset,它什么也不返回(即使应该返回),但在对其使用count()时仍然返回值1 以下是模型: import hashlib import random from django.contrib.auth import get_user_model from django.db import models class EmailChangeLogManager(models.Manager): def get_query_set(s

你可以猜到我有一个非常奇怪的问题。 我有一个queryset,它什么也不返回(即使应该返回),但在对其使用count()时仍然返回值1

以下是模型:

import hashlib
import random
from django.contrib.auth import get_user_model
from django.db import models


class EmailChangeLogManager(models.Manager):
    def get_query_set(self):
        return super(EmailChangeLogManager, self).get_query_set().filter(state=EmailChangeLog.PENDING)

    def create_new_request(self, user):
        request = self.model(user=user)
        request.save()
        return request


class EmailChangeLog(models.Model):
    """
    logs the users requests to change their email
    """
    PENDING = 0
    CHANGED = 1

    objects = EmailChangeLogManager()

    user = models.ForeignKey(get_user_model())
    token = models.CharField(max_length=40, primary_key=True)  # primary key so it blows up in case of collision
    state = models.SmallIntegerField()
    new_email = models.CharField(max_length=30)

    def __init__(self, user, * args, **kwargs):
        super(EmailChangeLog, self).__init__(self, *args, **kwargs)
        salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
        username = user.username
        if isinstance(username, unicode):
            username = username.encode('utf-8')
        self.token = hashlib.sha1(salt+username).hexdigest()
        self.user = user
        self.state = EmailChangeLog.PENDING
以下是视图中使用IndexError失败的部分:

if EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING).count() > 0:
    context['new_email'] = EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING)[0].new_email
在放置断点后,我运行了以下行:

>>> EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING).count()
Out[1]: 1
>>> EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING)
Out[2]: []
>>> EmailChangeLog.objects.all().count()
Out[3]: 2
>>> EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING).count()
Out[4]: 1
>>> EmailChangeLog.objects.filter(user=self.request.user, state=EmailChangeLog.PENDING)
Out[5]: []
>>> EmailChangeLog.objects.all().count()
Out[6]: 2
>>> EmailChangeLog.objects.all()
Out[7]: []
>>> EmailChangeLog.objects.filter(user=self.request.user)
Out[8]: []
>>> EmailChangeLog.objects.filter(state=EmailChangeLog.PENDING)
Out[9]: []
>>> EmailChangeLog.objects.filter()
Out[10]: []
>>> EmailChangeLog.objects.all()
Out[11]: []
>>> EmailChangeLog.objects.all().count()
Out[1]: 2
>>> EmailChangeLog.objects.all()
Out[3]: []
>>> EmailChangeLog.objects.all()
Out[5]: []
>>> EmailChangeLog.objects.all().count()
Out[6]: 2
>>> EmailChangeLog.objects.all().count()
Out[7]: 2
>>> az = EmailChangeLog.objects.all()
>>> az
Out[9]: []
>>> az.count()
Out[10]: 2
这是django的bug吗?如果不是,发生了什么

PS:我正在使用django 1.5.1


编辑:使用manage shell_plus时也会发生同样的情况,所以我找到了问题所在,问题出在init函数中,我去掉了它,改用了我的经理代码,但我仍然认为django一侧的queryset有问题

class EmailChangeLogManager(models.Manager):
    def get_query_set(self):
        return super(EmailChangeLogManager, self).get_query_set().filter(state=EmailChangeLog.PENDING)

    def create_new_request(self, user):
        request = self.model()
        salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
        username = user.username
        if isinstance(username, unicode):
            username = username.encode('utf-8')
        request.token = hashlib.sha1(salt+username).hexdigest()
        request.user = user
        request.save()
        return request
编辑:

似乎发生了两件事:

1) 您以与Django不兼容的方式重写了模型的init 期待。您不能向其中添加用户arg,您可能可以使用用户kwarg。 基本上,签名必须是*args、**kwargs,否则Django将无法加载 你的模型从数据库返回

2) Python(IIRC)中有一个bug,它会导致列表(qs)中的错误被吞没 返回错误并返回空列表。这在1.6中是固定的

这个错误似乎在1.6中得到了修复


这不是一个bug。queryset对象的求值是惰性的——这意味着它不会获取queryset结果,除非它被使用。例如:即使
emailchangelg.objects.filter(user=self.request.user,state=emailchangelg.PENDING)
返回
[]
-如果执行
emailchangelg.objects.filter(user=self.request.user,state=emailchangelg.PENDING)[:1]
-它将返回一个查询集,因为在该时间点对其进行求值。@karthikr:使用索引0访问它会引发索引器异常,打印查询也会使用它吗?顺便问一下:[:0]sameI是指
[:1]
还是
[0]
索引器失败:列表索引超出范围range@maazza:当您执行类似于
objects.all()[0]