I\'m trying to add some extra attributes to the elements of a QuerySet so I can use the extra information in templates, instead of hitting the database multiple times. Let m
This is an old question, but I'll add my solution because I needed it recently.
Ideally we could use some sort of proxy object for the QuerySet. Our proxy version would then make the changes during iteration.
It will be hard to cover all possible scenarios, QuerySet objects are a little complicated and are used in many different ways. But for the simple case of adding an attribute at the last minute because sending to a template (or generic view), the following might work:
class alter_items(object):
def __init__(self, queryset, **kwargs):
self.queryset = queryset
self.kwargs = kwargs
# This function is required by generic views, create another proxy
def _clone(self):
return alter_items(queryset._clone(), **self.kwargs)
def __iter__(self):
for obj in self.queryset:
for key, val in self.kwargs.items():
setattr(obj, key, val)
yield obj
And then use this like so:
query = alter_items(Book.objects.all(), price=2)
Because it is not a true proxy, you may need to make further modifications depending on how it is used, but this is the rough approach. It would be nice if there were an easy way to make a proxy class in Python with new style classes. The external library wrapt might be useful if you want to go with a more complete implementation