Opened 3 years ago

Last modified 23 months ago

#18142 new Bug

sorting in change_list is not distincted

Reported by: nick.mayerhofer@… Owned by: nobody
Component: contrib.admin Version: 1.4
Severity: Normal Keywords: sort distinct
Cc: tomek@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

class Appointment(models.Model):
    link = models.ForeignKey(MainData)
    date = models.DateField()

class MainData(models.Model):
    def filteredAppointment1(self):
        return Appointment.objects.filter().latest('date') #my special filter1
    filteredAppointment1.admin_order_field = 'appointment__date'

    def filteredAppointment2(self):
        return Appointment.objects.filter().latest('date') #my special filter2
    filteredAppointment2.admin_order_field = 'appointment__date'

After sortig it in admin change_list it ends up as a
Cartesian product of [filteredAppointment1 x filteredAppointment2]. Which means: NOT distincted.

Change History (4)

comment:1 Changed 3 years ago by andrewgodwin

  • Component changed from Database layer (models, ORM) to contrib.admin
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Bug

Related to #13902 - probably just needs the code that detects distinct-setting updated.

comment:2 Changed 23 months ago by oinopion

Consider following:

# models.py
class Case(models.Model):
    name = models.CharField(max_length=100)

class Appointment(models.Model):
    case = models.ForeignKey(Case, related_name='appointments')
    date = models.DateTimeField(default=timezone.now)

# console 
>>> print Case.objects.order_by('appointments__date').distinct().query
SELECT DISTINCT "a_case"."id", "a_case"."name", "a_appointment"."date" FROM "a_case" LEFT OUTER JOIN "a_appointment" ON ( "a_case"."id" = "a_appointment"."case_id" ) ORDER BY "a_appointment"."date" ASC

Distinct does not really work in this case, because order_by needs to pull one-to-many field into select clause, rows thus are unique and "non-distinctable".

I'm don't know what to do here. I'm not really sure if it's a real bug.

comment:3 Changed 23 months ago by oinopion

  • Cc tomek@… added

comment:4 Changed 23 months ago by akaariai

I think ordering by one-to-many join is a bug in itself. It is useful if you happen to know that you have constrained the one-to-many to unique field somehow (I believe this should work: .filter(translations__lang='fi').order_by('translations__name')). But if you have this data:

a1 -> b1 (col=1)
   -> b2 (col=4)
a2 -> b3 (col=2)
   -> b4 (col=3)

there isn't anything sane the ORM (or the admin) can do for A.objects.order_by(b__col). The ordering for distinct objects simply isn't defined.

So, I don't think we can remove the ability to order_by one-to-many as the user might have restricted the many side to unique object, but on the other hand we can't actually do anything sane for one-to-many ordering if there are actually many objects on the many side.

Maybe we can find a better way for this special one-to-many restricted to one-to-one ordering case. Until that day this ticket seems impossible to solve.

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