24👍
QuerySets in Django are actually generators, not lists (for further details, see Django documentation on QuerySets).
As such, there is no shortcut to get the index of an element, and I think a plain iteration is the best way to do it.
For starter, I would implement your requirement in the simplest way possible (like iterating); if you really have performance issues, then I would use some different approach, like building a queryset with a smaller amount of fields, or whatever.
In any case, the idea is to leave such tricks as late as possible, when you definitely knows you need them.
Update: You may want to use directly some SQL statement to get the rownumber (something lie . However, Django’s ORM does not support this natively and you have to use a raw SQL query (see documentation). I think this could be the best option, but again – only if you really see a real performance issue.
68👍
If you’re already iterating over the queryset and just want to know the index of the element you’re currently on, the compact and probably the most efficient solution is:
for index, item in enumerate(your_queryset):
...
However, don’t use this if you have a queryset and an object obtained by some unrelated means, and want to learn the position of this object in the queryset (if it’s even there).
- [Django]-How to refer to static files in my css files?
- [Django]-Exception: You cannot access body after reading from request's data stream
- [Django]-Django connection to postgres by docker-compose
57👍
If you just want to know where you object sits amongst all others (e.g. when determining rank), you can do it quickly by counting the objects before you:
index = MyModel.objects.filter(sortField__lt = myObject.sortField).count()
- [Django]-Select DISTINCT individual columns in django?
- [Django]-Customize/remove Django select box blank option
- [Django]-Sending an SMS to a Cellphone using Django
25👍
Assuming for the purpose of illustration that your models are standard with a primary key id
, then evaluating
list(qs.values_list('id', flat=True)).index(obj.id)
will find the index of obj
in qs
. While the use of list
evaluates the queryset, it evaluates not the original queryset but a derived queryset. This evaluation runs a SQL query to get the id fields only, not wasting time fetching other fields.
- [Django]-Celery task that runs more tasks
- [Django]-Django: "projects" vs "apps"
- [Django]-Testing admin.ModelAdmin in django
9👍
It’s possible for a simple pythonic way to query the index of an element in a queryset:
(*qs,).index(instance)
This answer will unpack the queryset into a list, then use the inbuilt Python index function to determine it’s position.
- [Django]-Get path of virtual environment in pipenv
- [Django]-What is the path that Django uses for locating and loading templates?
- [Django]-ValueError: Missing staticfiles manifest entry for 'favicon.ico'
5👍
You can do this using queryset.extra(…)
and some raw SQL like so:
queryset = queryset.order_by("id")
record500 = queryset[500]
numbered_qs = queryset.extra(select={
'queryset_row_number': 'ROW_NUMBER() OVER (ORDER BY "id")'
})
from django.db import connection
cursor = connection.cursor()
cursor.execute(
"WITH OrderedQueryset AS (" + str(numbered_qs.query) + ") "
"SELECT queryset_row_number FROM OrderedQueryset WHERE id = %s",
[record500.id]
)
index = cursor.fetchall()[0][0]
index == 501 # because row_number() is 1 indexed not 0 indexed
- [Django]-Django query datetime for objects older than 5 hours
- [Django]-How to implement followers/following in Django
- [Django]-How to handle request.GET with multiple variables for the same parameter in Django