#20795: Weird queryset behaviour and count() method
----------------------------------------------+----------------------------
     Reporter:  maa@…                         |      Owner:  nobody
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  1.5
     Severity:  Release blocker               |   Keywords:  count queryset
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+----------------------------
 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.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/20795>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/059.ad20d9d006a37dafa342226b21e391d5%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to