Opened 12 years ago

Closed 10 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 Changed 12 years ago by Aymeric Augustin

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 Changed 12 years ago by Jacob

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 Changed 11 years ago by anonymous

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

comment:4 Changed 11 years ago by Mike Fogel

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.

comment:5 in reply to:  3 Changed 11 years ago by alan@…

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 Changed 10 years ago by jeremyt

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 Changed 10 years ago by Daniel Sokolowski

Cc: ognajd@… added
Version: 1.3

comment:8 Changed 10 years ago by loic84

Newer ticket with related discussion: #20625

comment:9 Changed 10 years ago by Tim Graham

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