Opened 13 years ago

Closed 11 years ago

#16748 closed New feature (wontfix)

Documentation on creating custom querysets

Reported by: lee@… Owned by: nobody
Component: Documentation Version:
Severity: Normal Keywords:
Cc: mike@…, ognajd@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently Django's documentation describes how customize the manager's initial query set (https://docs.djangoproject.com/en/dev/topics/db/managers/#modifying-initial-manager-querysets), but not how to create filters that can be used on an existing query set, at any position in the chain of filters.

Doing so requires subclassing the queryset object. This blog post describes the issue in more detail and proposes a solution:

http://zmsmith.com/2010/04/using-custom-django-querysets/

It would be helpful if there were an officially approved way to subclass querysets or add custom chainable filters, and it was part of the documentation.

Change History (9)

comment:1 by Aymeric Augustin, 13 years ago

Triage Stage: UnreviewedDesign decision needed

The solution described in the blog post requires five lines of boilerplate code, which is a blocker for recommending it in the official documentation:

class CustomManager(models.Manager):

    def get_query_set(self):
        return CustomQuerySet(self.model)

    def __getattr__(self, name):
        return getattr(self.get_query_set(), name)

Currently, the docs just describe the APIs of Manager and QuerySet.

I don't know if there's a general solution to this problem, if we want to develop one in Django, or just let each developer figure out what's most appropriate in his/her situation.

comment:2 by Jacob, 13 years ago

Triage Stage: Design decision neededAccepted
Type: UncategorizedNew feature

There really ought to be a better way of making a manager and custom queryset all in one step -- it's a common operation. But until then we should document the crufty way.

comment:3 by anonymous, 12 years ago

How about something like this:
https://github.com/zacharyvoase/django-qmethod

comment:4 by Mike Fogel, 12 years ago

Cc: mike@… added

Note that the __getattr__ definition in the above boilerplate code violates https://docs.djangoproject.com/en/dev/topics/db/managers/#implementation-concerns

Associated discussion on #15062.

in reply to:  3 comment:5 by alan@…, 12 years ago

Replying to anonymous:

How about something like this:
https://github.com/zacharyvoase/django-qmethod

I second this method (or at least its syntax). I haven't tested it yet in my project, but it looks quite elegant. To me, the use of a separate Manager class makes sense when you might reuse that manager for two different models, but for my app, I usually just need one-off managers anyway. Being able to define custom queryset methods inline in the model class in most cases would make my business logic much simpler.

comment:6 by jeremyt, 12 years ago

Would something like adding queryset class as an optional parameter to models.Manager make the story a bit cleaner?

class CustomManager(models.Manager):
    def __init__(self, query_set_class=CustomQuerySet):
        super(CustomManager, self).__init__(query_set_class=query_set_class)

The code change would look like this: https://github.com/jtillman/django/compare/CustomQuerySet

comment:7 by Daniel Sokolowski, 11 years ago

Cc: ognajd@… added
Version: 1.3

comment:8 by loic84, 11 years ago

Newer ticket with related discussion: #20625

comment:9 by Tim Graham, 11 years ago

Resolution: wontfix
Status: newclosed

It seems like the related ticket has momentum, so it's probably not worth documenting "the crufty way" at this point.

Note: See TracTickets for help on using tickets.
Back to Top