簡體   English   中英

帶有計數的Django queryset中的錯誤?

[英]Bug in Django queryset with count?

如您所料,我遇到了一個非常奇怪的問題。 我有一個查詢集,它什么也不返回(即使應該返回),但在其上使用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中的錯誤嗎? 如果不是,那是怎么回事?

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預期不兼容的方式覆蓋了模型的初始化。 您不能向其中添加用戶arg,而可以使用用戶kwarg代替。 基本上,簽名必須是* args,** kwargs,否則Django將無法從DB重新加載模型。

2)Python(IIRC)中存在一個錯誤,該錯誤會導致list(qs)內部的錯誤吞噬錯誤並返回空列表。 在1.6中已修復。

似乎此錯誤已在1.6中修復。

https://code.djangoproject.com/ticket/20795#comment:4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM