Wednesday, October 6, 2010

Django and the none()

The Django manager has a none() method that can retury an empty queryset:

http://thecatatemysourcecode.posterous.com/django-empty-queryset


django.db.models.manager.py:
def none(self):
        return self.get_empty_query_set()

def get_empty_query_set(self):
        return EmptyQuerySet(self.model)

django.db.models.query.py:
class EmptyQuerySet(QuerySet):
    def __init__(self, model=None, query=None):
        super(EmptyQuerySet, self).__init__(model, query)
        self._result_cache = []

    def __and__(self, other):
        return self._clone()

    def __or__(self, other):
        return other._clone()

    def count(self):
        return 0

    def delete(self):
        pass

    def _clone(self, klass=None, setup=False, **kwargs):
        c = super(EmptyQuerySet, self)._clone(klass, **kwargs)
        c._result_cache = []
        return c
I tried it out too:
>>> from apapa.events.models import Event

>>> Event.objects
>>> 

>>> Event.objects.none()
>>> []

>>> Event.objects.filter(id=100000000) (for a non-existent Event)
>>> []
The QuerySet class also has a __nonzero__() operator that is used when there is an if statement used, which makes the logic perform exactly the same if the queryset were actually a list.
__nonzero__(self)

Called to implement truth value testing, and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, __len__ is called, if it is defined. If a class defines neither __len__ nor __nonzero__, all its instances are considered true.
django.db.models.query.py:
def __nonzero__(self):
        if self._result_cache is not None:
            return bool(self._result_cache)
        try:
            iter(self).next()
        except StopIteration:
            return False
        return True

No comments:

Post a Comment