0

The issue is that if the database is allowed to sort results it sorts strings according to the C locale which yields awfully wrong results in my language. For example it considers all letters with diacritics to be after all ascii letters - so, for example, ś comes after z, while it should come in between s and t.

However, as long as I'm allowed to sort results in Python, I can easily tell Python how to sort according to the current locale. setlocale(LC_ALL, 'pl_PL.UTF-8') and then set the key for sorting to be the result of strxfrm applied to the model's string representation.

So, how can I force Django to sort results in Admin in Python and not in the database to circumvent the above issue?

  • 3
    Have you looked into setting the collation on your database? That'll solve the problem more generally, if there's not a specific reason you can't or don't want to do that. – Peter DeGlopper Aug 15 '17 at 15:57
  • @PeterDeGlopper The DB is currently SQLite which,as far as I'm aware, doesn't support setting collation in genenal, but only on per-query basis. I might be wrong here ofc, am I? –  Aug 15 '17 at 17:29
  • I'm no expert on SQLite, but from the docs it doesn't look like it provides any collations that would be useful here. So that looks like doing it in Python is the best option as long as you're on SQLite. The `get_queryset` answer seems like a good way to do that, not that I've looked for alternatives. – Peter DeGlopper Aug 15 '17 at 17:36
  • @PeterDeGlopper https://stackoverflow.com/a/615284/4385532 , but I don't know how to force Django to do this on every `order_by` query. –  Aug 16 '17 at 11:13
  • If the database collation is working as you'd like, Django should use it by default. You might have to specify the `ordering` meta parameter on the model: https://docs.djangoproject.com/en/1.11/ref/models/options/#ordering - that tells Django which field to sort on, while the collation tells the database how to implement the sort. – Peter DeGlopper Aug 16 '17 at 14:11

1 Answers1

3

As a commenter pointed out, getting the collation in the database set properly seems like a more appropriate solution, especially since databases were made to do these type of things in a performant manner (sorting, ordering, etc.).

However, if you prefer to do it in python, you could override the get_queryset method in your admin class, and put whatever code you want in there, as shown in the docs.

MrName
  • 2,363
  • 17
  • 31
  • The DB is currently SQLite which,as far as I'm aware, doesn't support setting collation in genenal, but only on per-query basis. I might be wrong here ofc, am I? –  Aug 15 '17 at 17:29
  • I don't think SQLite supports collation settings. Are you planning on running in production on SQLite? I don't think that is particularly common, people generally use it for local development only, and then use a standard database system for production. – MrName Aug 15 '17 at 17:38
  • This is an academic assignment... So while SQLite might not be the best choice to run in the production I don't think this is an issue here. –  Aug 16 '17 at 10:32
  • Thank you for your answer but, tbh, I'm still not sure how should I do this. I am aware of the possibility to override `get_queryset` and in fact I've already done this for a different reason. However, I'm not sure how can this be helpful. First, AFAIK, the code responsible for ordering doesn't even belong to `get_queryset`. Rather, when the user clicks on an orderable column in the admin, Django automatically appends `order_by()` to whatever query is returned by `get_queryset`. Also `get_queryset` is supposed to return a `QuerySet` (duh), while applying `sorted` to a `QuerySet` returns a list –  Aug 16 '17 at 10:48
  • Ah, I misunderstood your question @gaazkam, you are trying to override the clickable filters in the admin section. It has been a long time since I had to do this, will do some research and get back to you. – MrName Aug 16 '17 at 16:37