#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.