﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
20795	Weird queryset behaviour and count() method	maa@…	nobody	"I am having a really weird issue.
I have a queryset who returns nothing(even when it should) but still returns a value of one when using count() on it.

Here are the models:

    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

And here is the part of the view who fails with 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

I ran the following lines after after putting a break point:

    >>> 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

Is this a bug in django ? If not what is going on ?
I am using django 1.5.1
The same happens using manage shell_plus

I got rid of it by using a manager's method instead of the __init__ function, if somehow this is not a bug can you please tell me what is going on and how can an empty queryset return a value greater than zero ?

Thanks."	Bug	closed	Database layer (models, ORM)	1.5	Release blocker	invalid	count queryset		Unreviewed	0	0	0	0	0	0
