Fixed #29538 -- Added support for ordering related objects by query expressions.#10146
Conversation
Added support for ordering related objects by query expressions
| attrgetter('name') | ||
| ) | ||
|
|
||
| @skip('What should the behavior be?') |
There was a problem hiding this comment.
Not sure what the expected behavior here is.
class Album:
class Meta:
ordering = [models.F('artist').asc(nulls_last=True)]class Album:
class Meta:
ordering = ['artist']Should both of these work the same way? Or does
the first mean "order by artist_id"
and the second mean "order by the default order of Musician"?
There was a problem hiding this comment.
Pretty sureordering = ['artist'] will mean order by artist (rather than the default order of the related model). (In the compiler, field names get converted to column references, rather than resolved via related models' Meta...)
Possible to check that though...
There was a problem hiding this comment.
@carltongibson no, you should useartist_id if you want to achieve that. There's a documented difference between order_by('artist') and order_by('artist_id') as it was not even possible to disable related ordering before 24ec953.
Given Artist.Meta.ordering = ['foo', F('bar').asc(nulls_last=False)]
then Album.Meta.ordering = [models.F('artist').asc(nulls_last=True)]should be the equivalent of
[F('artist__foo').asc(nulls_last=True), F('artist__bar').asc(nulls_last=True)]
django/db/models/sql/compiler.py
Outdated
| order, already_seen)) | ||
|
|
||
| def _join_strings(*strings): | ||
| return LOOKUP_SEP.join(filter(None, strings)) |
There was a problem hiding this comment.
What is this for? Is the filter() necessary? Couldn't this just be inlined below?
There was a problem hiding this comment.
I think this is the alternative
if prefix is None:
new_prefix = name
else:
new_prefix = prefix + LOOKUP_SEP + nameprefix is None at the top of the recursive call.
Which is better?
The old name 'find_ordering_name' was no longer describing what this function was doing 9 years since it was named. convert_to_expression seems to fit better.
carltongibson
left a comment
There was a problem hiding this comment.
Thanks for the input here. Sorry for the slowish pick-up.
One initial point on the placement of the tests:
Can we include these in the existing ordering app?
- We try not to add new models if we can avoid it. (They slow everything down.) Can we re-use or adjust the
ordering.modelsmodels? - Can we move
order_with_expression.testsintoorderingtoo? (Either in a test case intests.pyor a separatetest_....pyfile if your prefer.)
|
@carltongibson I tried reusing the models at first but they weren't quite structured in the right way for my tests. I'll give it another try, possibly restructuring the existing tests to accommodate. |
|
@alexandrelaplante Thanks! (Perhaps if you move the tests all into |
auvipy
left a comment
There was a problem hiding this comment.
please rebase and address carls comments
|
Closing due to inactivity. |
Added support for ordering related objects by query expressions
https://code.djangoproject.com/ticket/29538