Opened 5 years ago

Closed 5 years ago

#30061 closed New feature (duplicate)

annotate boolean from a Q object

Reported by: Ryan Hiebert Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I think that I saw something about this on the Django-Developers mailing list years ago, but I cannot find the reference, unfortunately.

I have on several occasions needed to annotate a boolean. The way that I have found to do this is to use a conditional expression, but it seems awfully noisy to my eyes. It seems like it might be better to allow directly annotating Q objects, or perhaps providing a simple wrapper to convert a Q object into a boolean field expression.

For example, instead of this:

notes = notes.filter(user=self.user).annotate(
    is_author=Case(
        When(author_id=self.request.user.id, then=True),
        default=Value(False),
        output_field=BooleanField(),
    ),
)

I think that there's a good case to be made that this should be possible:

notes = notes.filter(user=self.user).annotate(
    is_author=Q(author_id=self.request.user.id),
)

Or if we really can't have the Q object doing double duty, we could wrap that Q object in some expression constructor. I didn't provide an example, because I couldn't think of a great and obvious name for such a constructor.

Change History (3)

comment:1 by Simon Charette, 5 years ago

Component: UncategorizedDatabase layer (models, ORM)
Triage Stage: UnreviewedAccepted
Type: UncategorizedNew feature
Version: 2.1master

It currently works and is tested with an ExpressionWrapper (see #26517) but allowing direct usages of Q would definitely be simpler.

comment:2 by Ryan Hiebert, 5 years ago

Thank you for letting me know that, Simon. That's such a useful feature, that even if using Q objects directly is rejected for some reason (though I hope not), it would be very useful to document that it is possible to use Q objects in an ExpressionWrapper.

For anyone that might come across this issue looking for this feature, the syntax that currently works and is tested is like this:

notes = notes.filter(user=self.user).annotate(
    is_author=ExpressionWrapper(
        Q(author_id=self.request.user.id),
        output_field=BooleanField(),
    ),
)

comment:3 by Simon Charette, 5 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #27021.

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