about QuerySet

21 views
Skip to first unread message

newme

unread,
Jan 20, 2012, 3:12:23 AM1/20/12
to Django users
user = User.objects.filter(pk="XXXX")
user is a QuerySet

every time i call user[0], i returns a different reference.

maybe it should be a python question.
i want to know i QuerySet does that.

akaariai

unread,
Jan 29, 2012, 7:29:21 PM1/29/12
to Django users
The reason is that Django does not do "instance caching". That is, you
will get different reference each time from a queryset because that is
how it works. If you need to use the same instance, then you need to
store that somewere yourself. This is all the help I can give based on
your question.

- Anssi

newme

unread,
Feb 1, 2012, 2:36:34 AM2/1/12
to Django users
do you mean that queryset will query database every time i call
user[0]?

akaariai

unread,
Feb 1, 2012, 3:34:14 AM2/1/12
to Django users
On Feb 1, 9:36 am, newme <dllizh...@gmail.com> wrote:
> do you mean that queryset will query database every time i call
> user[0]?

Yes. That is exactly what happens:
In [7]: qs[0]
Out[7]: <OrganisaatioOsa: THL - Terveyden ja hyvinvoinnin laitos>
In [9]: print connection.queries
[{'time': '0.011', 'sql': 'SELECT ... FROM "organisaatio_osa" LIMIT
1'}]

In [10]: qs[0]
Out[10]: <OrganisaatioOsa: THL - Terveyden ja hyvinvoinnin laitos>
In [11]: print connection.queries
[{'time': '0.011', 'sql': 'SELECT ... FROM "organisaatio_osa" LIMIT
1'},
{'time': '0.001', 'sql': 'SELECT ... FROM "organisaatio_osa" LIMIT
1'}]

If you do not want this to happen, you can evaluate your queryset into
a list first by:
objlist = list(qs[0:wanted_limit])
and now objlist is just a regular Python list.

The lazy evaluation of querysets can be a little surprising sometimes.
Using django-debug-toolbar or just settings.DEBUG = True, and then
print connection.queries is recommended :)

- Anssi

Daniel Roseman

unread,
Feb 1, 2012, 5:02:12 AM2/1/12
to django...@googlegroups.com
On Wednesday, 1 February 2012 08:34:14 UTC, akaariai wrote:
Slight clarification: the slicing will only trigger a db call if the queryset has not been evaluated. Converting it to a list is one way of doing that, but if you iterate the queryset in any way it will populate the internal cache and not call the database on subsequent slices.
--
DR.

newme

unread,
Feb 2, 2012, 10:52:27 PM2/2/12
to Django users
so it means when i call user[1] after user[0], it is possible that i
will get same record if someone else insert a new record into database
between 2 calls.

akaariai

unread,
Feb 3, 2012, 3:29:01 AM2/3/12
to Django users


On Feb 3, 5:52 am, newme <dllizh...@gmail.com> wrote:
> so it means when i call user[1] after user[0], it is possible that i
> will get same record if someone else insert a new record into database
> between 2 calls.

Actually, there doesn't need to be an insert between the calls if you
don't use .order_by(). Technically, without an ORDER BY the database
is free to return the records in any order it wishes, even if there
are no inserts in between.

I think you really should fetch all the needed objects in one go. That
is the correct way to do what you need. And in addition it is more
efficient.

- Anssi

newme

unread,
Feb 7, 2012, 6:36:04 AM2/7/12
to Django users
thank you.
then a basic python question.
how does queryset implement it?
does python also allow operator (e.g. []) overloading?

Daniel Roseman

unread,
Feb 7, 2012, 6:58:05 AM2/7/12
to django...@googlegroups.com
On Tuesday, 7 February 2012 11:36:04 UTC, newme wrote:
thank you.
then a basic python question.
how does queryset implement it?
does python also allow operator (e.g. []) overloading?


It's not usually called overloading in Python, but yes. Classes can define a `__getitem__` method which determines what to do when the square-bracket notation is used. You can see the code here:
--
DR. 

newme

unread,
Feb 7, 2012, 8:39:09 PM2/7/12
to Django users
thank you so much.
> notation is used. You can see the code here:https://code.djangoproject.com/browser/django/trunk/django/db/models/...
> --
> DR.
Reply all
Reply to author
Forward
0 new messages