Reputation: 1275
The requirement is for me to be able to access members of an evaluated QuerySet by a string attribute, in this case name
. I don't like the idea of looping over a QuerySet as it seems like there is a more efficient way.
After I've called something like:
my_objects = MyObject.objects.all()
And I evaluate it with something like:
len(my_objects)
What is the best way to get a specific result by name from an evaluated QuerySet, in this case my_objects
? Ideally I'd like to see something like my_objects.filter(foo='bar')
.
Note I'll need all of the results in the evaluated QuerySet during the course of the process, so that's why I have it in one initial query.
Upvotes: 3
Views: 2187
Reputation: 14325
@aamir-rind's solution is great, but it only works if name
is unique.
If name
is not unique, you could, for example, collect the objects in a list:
# map name to list of objects
my_objects_dict = dict()
for obj in my_objects:
key = obj.name
if key not in my_objects_dict:
my_objects_dict[key] = []
my_objects_dict[key].append(obj)
If my_objects
has not been evaluated yet, the loop will evaluate it. If my_objects
has already been evaluated, e.g. as in my_objects = list(MyModel.objects.all())
, it will not be evaluated again.
Upvotes: 0
Reputation: 4169
Evaluated queryset is a list. There is no indexation of list elements, so looping is required anyway. But evaluated queryset is assumed to be not so huge, max few hundreds of entries so looping is ok. Do not evaluate large querysets.
By the way, similar lists of objects are created by prefetch_related()
. There is an implementation of ListQuerySet
which supports many filters, ordering and distinct, making possible to run many (not all though) queries for such lists of objects:
https://github.com/Dmitri-Sintsov/django-jinja-knockout/blob/master/django_jinja_knockout/query.py
Upvotes: 0
Reputation: 39689
There is no direct way of doing this to get a object based on field value from queryset. But you can do one thing is to create a dictionary from queryset and set name
as key (must be unique):
my_objects = MyObject.objects.all()
obj_dict = {obj.name: obj for obj in my_objects}
print obj_dict['any_name']
FYI: If you want to just retrieve a single object from table then you can use .get method:
obj = MyObject.objects.get(pk=id)
or
obj = MyObject.objects.get(name='unique_name')
Upvotes: 3