I'm using django-parler on several models. Usually, you apply parler to fields like title, name etc and of course you would want to be able to sort these in the Django admin. The closest I've come to do this is by overriding the queryset method on the ModelAdmin, but it seems like an awfully crude way to do it. Also, it only sets the default sorting and you can't click-header-sort the field.
class MyModelAdmin(TranslatableAdmin):
list_display = ['title', 'language_column']
def get_queryset(self, request):
language_code = settings.LANGUAGE_CODE
qs = Grant.objects.translated(language_code).order_by('translations__title')
return qs
So the question is: Can you make translated fields sortable in the admin? And it doesn't matter if you have to show or hardcode it only to the default language since it's only used by administrators.
This is an area where we're struggling as well. Your example is quite suitable for sorting, as you limit the list to a single language using .translated(..)
.
To sort things, you can follow the standard ModelAdmin logic, where the list is filtered:
class MyAdmin(TranslatableAdmin):
list_display = ('title_column', ...)
def title_column(self, object):
return object.title
title_column.short_description = _("Title")
title_column.admin_order_field = "translations__title"
def get_queryset(self, request):
# Limit to a single language!
language_code = self.get_queryset_language(request)
return super(MyAdmin, self).get_queryset(request).translated(language_code)
Note that this code currently hides all objects that aren't translated!
With the regular queryset, using .order_by('translations__title')
won't work because you could either hit the translated or fallback row first. Such a thing could only be achieved with custom SQL. For example:
SELECT project.id,
translation.language_code,
translation.title,
fallback.title,
COALESCE(translation.title, fallback.title) AS order_title
FROM "myapp_project" AS project
LEFT OUTER JOIN "myapp_project_translation" AS translation ON (translation.master_id = project.id AND translation.language_code = 'nl')
LEFT OUTER JOIN "myapp_project_translation" AS fallback ON (fallback.master_id = project.id AND fallback.language_code = 'en')
ORDER BY order_title
With a mix of .extra()
and admin_order_field
you might be able to get this to work, but using .translated()
surely makes things easier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With