Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#14837 closed (wontfix)

field based custom ordering

Reported by: Peter of the Norse <RahmCoff+dj@…> Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I have a model of bands. The problem is, “The Beatles”, along with most of the other bands are filed under ‘T’. I want them right after “Beat Happening”. So I wrote a simple function to do that. if arg[0][0:4] == 'The ': return arg[0][4:] basically. PostgreSQL allows indexes on functions, so no performance problem. Until I try to use it in Django. I wrote this workaround:

SansTheManager(models.Manager):
    def get_query_set(self):
        return super(SansTheManager, self).get_query_set().\
            extra(select={'_sans_the_order': 'sans_the(name)'},\
            order_by=['_sans_the_order'])

class Band(models.Model):
    name = CharField('Band name', max_length=255, unique=True)

    objects = SansTheManager()

This works, until I try to use it in the Admin interface. Then the order goes out the window. Also, I have to use order_by('other_field', '_sans_the_ordering') which looks ugly. And that does happen. So I would like to be able to order by expressions somehow. My ideal solution would involve using fields to provide the ordering. That way it would work with Admin too.

My suggestion:

class Band(models.Model):
    name = CharField('Band name', max_length= 255, unique= True, ordering= 'sans_the(name)')

    class Meta:
        ordering = 'name',

Change History (2)

comment:1 Changed 4 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

I'm going to mark this wontfix, but only because the specific API you're proposing wouldn't be required if a two other API features -- features that have been in the proposal pile for a while -- existed. In particular:

  • The ability to use annotate() to attach non-aggregate clauses to models
  • Denormalized fields on a model.

With these two features, you could denormalize a 'sans_the' field onto model, and then use normal ordering to point to that field -- no special field handling required.

Yet another approach would be to extend the handling of ordering to accept expressions.

So - yes, the use case is reasonable, but this doesn't require special handling on a field.

comment:2 Changed 4 years ago by Peter of the Norse <RahmCoff+dj@…>

I really didn’t expect this to be considered because it’s a bit far out, but your solutions aren’t much better than what I have now. Annotating extra fields is just like extra(select=kwargs), and I can denormalize a field by overriding save(). They wouldn’t solve my current problems.

  • The admin interface doesn’t sort my way when I click on the “Band name” header
  • Views that need to explicitly sort by name have to use an awkward value.

I can accept the second one. If I don’t like the value I can change it, but the other problem with the admin site is still there. Is there any way to change that? Perhaps I should open another ticket for that.

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