[Django] #30460: ManyToMany relationships with a custom `through` do not respect Meta.ordering on the intermediary model

14 views
Skip to first unread message

Django

unread,
May 7, 2019, 5:34:33 PM5/7/19
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: | Owner: nobody
ryanpetrello |
Type: Bug | Status: new
Component: Database | Version: 2.2
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
`ManyToManyField`s that specify an intermediary model with a custom
`Meta.ordering` do not inherit that ordering.

{{{#!python
class Dog(models.Model):
pass


class OrderedMembership(models.Model):

class Meta:
ordering = ('position',)

dog = models.ForeignKey('Dog', models.CASCADE)
winner = models.ForeignKey('Winner', models.CASCADE)
position = models.PositiveIntegerField()


class Winner(models.Model):
name = models.CharField(max_length=128)
# OrderedMembership object defined as a class
members = models.ManyToManyField(Dog, through=OrderedMembership)

lassie = Dog('Lassie')
fido = Dog('Fido')
rover = Dog('Rover')
dog_show = Winner(name='Dog Show')
OrderedMembership.objects.create(dog=lassie, winner=dog_show, position=3)
OrderedMembership.objects.create(dog=fido, winner=dog_show, position=2)
OrderedMembership.objects.create(dog=rover, winner=dog_show, position=1)

dog_show.members.all() # <--- does not respect
`OrderedMembership.position`


}}}

This means that if you want to create a custom M2M model that manages
default order via some column on the M2M table:

https://github.com/ansible/awx/pull/3842/files#diff-
ea6da88b8c0cd3fbf7858ae87933b296R995
https://github.com/gregmuellegger/django-
sortedm2m/blob/b48481ebd1212f1af22a6a04d1c8372b5a837350/sortedm2m/fields.py#L41

...it doesn't work as you'd expect (the M2M relation falls back to natural
database order - usually the primary key of the target model).

--
Ticket URL: <https://code.djangoproject.com/ticket/30460>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 7, 2019, 11:12:02 PM5/7/19
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: ryanpetrello | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 2.2
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* needs_better_patch: 0 => 1
* has_patch: 0 => 1
* type: Bug => New feature
* stage: Unreviewed => Accepted


Comment:

I wouldn't say this is actually a bug as many-to-many field managers have
always supported ordering on their referenced model

Adding support for `through._meta.ordering` has backward compatibility
concerns as we have to decide how to deal with `ordering` defined on both
the `through` and `to` model. Should the `through` ordering have
precedence over the `to`ordering? Should they be merged together? We also
have to make sure whatever we do regarding ordering translation honors the
mechanisms in place to exclude `Meta.ordering` from aggregation as naively
translating it into an `order_by` call will bypass the checks added in
1b1f64ee5a78cc217fead52cbae23114502cf564 for #14357.

In my opinion the resulting ordering should be `through._meta.ordering` +
`to._meta.ordering`. This might require a django-developers thread to
gather feedback though.

Accepting the ticket on the basis that it seems like a feature that should
be supported but the current PR requires significant adjustments first.

--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:1>

Django

unread,
Sep 29, 2019, 9:05:01 AM9/29/19
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: Ryan Petrello | Owner: nobody

Type: New feature | Status: new
Component: Database layer | Version: master

(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Asif Saifuddin Auvi):

* version: 2.2 => master


--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:2>

Django

unread,
Dec 5, 2019, 11:22:54 AM12/5/19
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: Ryan Petrello | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Baptiste Mispelon):

I just closed #17344 as a duplicate. It was older but there wasn't much
discussion on that ticket so I figured I would keep this one open instead.

I'll also note that there's #17345 which is partially related (being able
to define an explicit ordering without using a through table).

--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:3>

Django

unread,
Sep 1, 2021, 5:37:14 PM9/1/21
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: Ryan Petrello | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: dev

(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by mnieber):

I just found out that you can use
`dog_show.members.all().order_by('orderedmembership')`. However, afaik,
this (surprising!) feature is not documented, would be nice to add this to
the docs.

--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:4>

Django

unread,
Mar 12, 2024, 2:00:43 AM3/12/24
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: Ryan Petrello | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ülgen Sarıkavak):

* cc: Ülgen Sarıkavak (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:5>

Django

unread,
May 26, 2024, 6:34:27 AM5/26/24
to django-...@googlegroups.com
#30460: ManyToMany relationships with a custom `through` do not respect
Meta.ordering on the intermediary model
-------------------------------------+-------------------------------------
Reporter: Ryan Petrello | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Dmytro Litvinov):

* cc: Dmytro Litvinov (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/30460#comment:6>
Reply all
Reply to author
Forward
0 new messages