Hi Malcolm, After the queryset-refactor merge, code like this breaks:
Foo.objects.none() | Foo.object.filter(bar=123) (This kind of thing is useful sometimes when building up a QuerySet in stages. That isn't one of the use cases given for .none() in the docs, but the test suite does say "none() returns an EmptyQuerySet that behaves like any other QuerySet object", so it would be nice if the above worked). I've created a patch, which special cases EmptyQuerySet in a couple of places, which seems to be the simplest way of doing it. I can commit it myself, but I wanted to pass it by you first since I'm unfamiliar with qs-rf, and in case you disagree about fixing this -- patch attached. Luke -- "Where a person wishes to attract, they should always be ignorant." (Jane Austen) Luke Plant || http://lukeplant.me.uk/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---
Index: django/db/models/query.py =================================================================== --- django/db/models/query.py (revision 7509) +++ django/db/models/query.py (working copy) @@ -132,15 +132,25 @@ def __and__(self, other): self._merge_sanity_check(other) - combined = self._clone() - combined.query.combine(other.query, sql.AND) - return combined + if self.__class__ is EmptyQuerySet: + return self + elif other.__class__ is EmptyQuerySet: + return other + else: + combined = self._clone() + combined.query.combine(other.query, sql.AND) + return combined def __or__(self, other): self._merge_sanity_check(other) - combined = self._clone() - combined.query.combine(other.query, sql.OR) - return combined + if self.__class__ is EmptyQuerySet: + return other + elif other.__class__ is EmptyQuerySet: + return self + else: + combined = self._clone() + combined.query.combine(other.query, sql.OR) + return combined #################################### # METHODS THAT DO DATABASE QUERIES # @@ -495,6 +505,9 @@ """ Checks that we are merging two comparable queryset classes. """ + if self.__class__ is EmptyQuerySet or other.__class__ is EmptyQuerySet: + return + if self.__class__ is not other.__class__: raise TypeError("Cannot merge querysets of different types ('%s' and '%s'." % (self.__class__.__name__, other.__class__.__name__)) Index: tests/modeltests/lookup/models.py =================================================================== --- tests/modeltests/lookup/models.py (revision 7509) +++ tests/modeltests/lookup/models.py (working copy) @@ -270,6 +270,14 @@ 0 >>> [article for article in Article.objects.none().iterator()] [] +>>> Article.objects.none() | Article.objects.filter(headline='Article 1') +[<Article: Article 1>] +>>> Article.objects.none() & Article.objects.filter(headline='Article 1') +[] +>>> Article.objects.filter(headline='Article 1') | Article.objects.none() +[<Article: Article 1>] +>>> Article.objects.filter(headline='Article 1') & Article.objects.none() +[] # using __in with an empty list should return an empty query set >>> Article.objects.filter(id__in=[])