Code

Opened 3 years ago

Closed 12 months 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.

Attachments (0)

Change History (9)

comment:1 Changed 3 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design 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 3 years ago by jacob

  • Triage Stage changed from Design decision needed to Accepted
  • Type changed from Uncategorized to New 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 follow-up: Changed 2 years ago by anonymous

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

comment:4 Changed 21 months ago by carbonXT

  • 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 16 months 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 15 months 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 13 months ago by danols

  • Cc ognajd@… added
  • Version 1.3 deleted

comment:8 Changed 13 months ago by loic84

Newer ticket with related discussion: #20625

comment:9 Changed 12 months ago by timo

  • Resolution set to wontfix
  • Status changed from new to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.