Is there a way to augment django QuerySets with extra attributes?

前端 未结 5 1246
陌清茗
陌清茗 2021-01-14 19:06

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

5条回答
  •  忘掉有多难
    2021-01-14 19:34

    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

提交回复
热议问题