0

I have version field for a model, a string field. I defined my Django admin ordering by that field ("-version").
The problem is python's version comparison doesn't work when it comes to strings. For example:

vers=['5.10.0.','5.9.0','5.8.0']
vers[0]>vers[1]
>>False

Should be true.

How do I write custom ordering without changing the models?
I saw this question, but it works only for aggregation functions.

Note: I need solution for ordering, not list_filter, which I already have an answer here. I changed the lookup as follows:

def lookups(self, request, model_admin):
    qs = model_admin.queryset(request)
    vers = qs.values_list('version', flat=True).distinct().order_by('-version')
    s_vers = [tuple([int(x) for x in n.split('.')]) for n in vers]
    s_vers = sorted(s_vers, reverse=True)
    ns_vers = ['.'.join(map(str, x)) for x in s_vers]
    ret_vers = []

    for v in ns_vers:
        ret_vers.append((v, v))

    return ret_vers
Community
  • 1
  • 1
Ron D.
  • 3,774
  • 6
  • 31
  • 39
  • I don't think this would be possible in django admin. The ordering depends upon the model fields, and standard comparison between their values. ordering can't be applied using such complex comparison. – Rohit Jain Jul 31 '16 at 18:41

1 Answers1

3

Here is how I solved this:

class MyModelAdmin(admin.ModelAdmin):

    def get_queryset(self, request):
        qs = super(MyModelAdmin, self).get_queryset(request)
        qs = qs.extra(select={'nversion': "string_to_array(version, '.')::bigint[]"}).order_by('-nversion')
        return qs

    def vers(self, obj):
        return obj.nversion

    ordering = ('-nversion',)
Ron D.
  • 3,774
  • 6
  • 31
  • 39