Ticket #17271: none_custom_qs.patch

File none_custom_qs.patch, 3.5 KB (added by andreypopp, 4 years ago)

Patch for ticket #17271

  • django/db/models/manager.py

    diff --git a/django/db/models/manager.py b/django/db/models/manager.py
    index e1bbf6e..135943a 100644
    a b class Manager(object): 
    4646    # Tracks each time a Manager instance is created. Used to retain order.
    4747    creation_counter = 0
    4848
    49     def __init__(self):
     49    def __init__(self, queryset_cls=None):
    5050        super(Manager, self).__init__()
    5151        self._set_creation_counter()
    5252        self.model = None
    5353        self._inherited = False
    5454        self._db = None
     55        self._queryset_cls = queryset_cls or QuerySet
    5556
    5657    def contribute_to_class(self, model, name):
    5758        # TODO: Use weakref because of possible memory leak / circular reference.
    class Manager(object): 
    101102    #######################
    102103
    103104    def get_empty_query_set(self):
    104         return EmptyQuerySet(self.model, using=self._db)
     105        return self._queryset_cls(self.model, using=self._db).none()
    105106
    106107    def get_query_set(self):
    107108        """Returns a new QuerySet object.  Subclasses can override this method
    108109        to easily customize the behavior of the Manager.
    109110        """
    110         return QuerySet(self.model, using=self._db)
     111        return self._queryset_cls(self.model, using=self._db)
    111112
    112113    def none(self):
    113114        return self.get_empty_query_set()
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index be42d02..e78e9ad 100644
    a b class QuerySet(object): 
    582582        """
    583583        Returns an empty QuerySet.
    584584        """
    585         return self._clone(klass=EmptyQuerySet)
     585        klass = type(
     586            "_InstrumentedEmptyQuerySet_%s" % self.__class__.__name__,
     587            (EmptyQuerySet, self.__class__), {})
     588        return self._clone(klass=klass)
    586589
    587590    ##################################################################
    588591    # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
  • tests/modeltests/lookup/models.py

    diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py
    index 7c264a4..2506d7a 100644
    a b This demonstrates features of the database API. 
    55"""
    66
    77from django.db import models
     8from django.db.models.query import QuerySet
    89
     10class CustomArticleQuerySet(QuerySet):
     11
     12    def have_author1(self):
     13        return self.filter(author__name='Author 1')
    914
    1015class Author(models.Model):
    1116    name = models.CharField(max_length=100)
    class Author(models.Model): 
    1318        ordering = ('name', )
    1419
    1520class Article(models.Model):
     21    objects = models.Manager()
     22    custom_manager = models.Manager(CustomArticleQuerySet)
     23
    1624    headline = models.CharField(max_length=100)
    1725    pub_date = models.DateTimeField()
    1826    author = models.ForeignKey(Author, blank=True, null=True)
  • tests/modeltests/lookup/tests.py

    diff --git a/tests/modeltests/lookup/tests.py b/tests/modeltests/lookup/tests.py
    index 9c2b0c6..e12f3f3 100644
    a b class LookupTests(TestCase): 
    450450            [article for article in Article.objects.none().iterator()],
    451451            [])
    452452
     453    def test_none_custom_qs(self):
     454        self.assertQuerysetEqual(Article.custom_manager.none(), [])
     455        self.assertQuerysetEqual(
     456            Article.custom_manager.none().have_author1(),
     457            [])
     458
    453459    def test_in(self):
    454460        # using __in with an empty list should return an empty query set
    455461        self.assertQuerysetEqual(Article.objects.filter(id__in=[]), [])
Back to Top