Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin. Filter by available translations. #303

Open
eugened19 opened this issue Jun 30, 2016 · 3 comments
Open

Admin. Filter by available translations. #303

eugened19 opened this issue Jun 30, 2016 · 3 comments

Comments

@eugened19
Copy link

eugened19 commented Jun 30, 2016

Hi guys,

Tried to implement functionality to filter objects by available translations. (We can have 1+ translations for any object), so admin is able to display only objects available in certain language.

The only way I made it work was by using:
list_filter = ('translations__language_code', )
It gave me the search box with language codes.

Having a problem that it only shows me objects for some languages but not for the others.
In all cases it shows correct total number of results next to the search box.

I found only one pattern which might make sense (still sounds crazy though :) )
Objects are returned only for languages present in HTTP_ACCEPT_LANGUAGE header
I'm not sure if this guess even makes sense, but something is wrong for sure.

Django 1.8
Django-hvad 1.5.0

Please tell me if you need more info.

Thank you!
Eugene

@spectras
Copy link
Collaborator

Hello,
Thanks for reporting. Well, the thing is by specifying translations__language_code, which then results in a filter being applied on that same thing, TranslatableAdmin's mechanisms are bypassed. But they are still active, and will do its own filtering. So you end up filtering two times.

I am not sure, and have little time right now to check, but I believe what you want is too clever for current implementation of TranslatableAdmin and you will have to override some of its methods. I suggest you have a look at how it works, most notably its ̀get_querysetmethod. It is the one that is invoked by Django'sChangeListinternal class. Probably you'll need to tweak that internal class as well. You can override it using the admin'sget_changelist` internal method.

That's a lot of Django internals. Unfortunately, the sad truth is Django admin app is very monolithic and pretty hard to tweak outside of the cases it explicitly accounts for in its options.

@eugened19
Copy link
Author

eugened19 commented Jul 4, 2016

Hi,

Solved by going the following way:

class LangCountryFilter(SimpleListFilter):
    title = 'country' 
    parameter_name = 'country'

    def lookups(self, request, model_admin):
        countries = set(['US', 'Brazil', 'En', 'De', 'Pt', 'Fr', 'Es'])
        return [(c, c) for c in countries]

    def queryset(self, request, queryset):
        if self.value():
            print 'SELFVALUE: ' + repr(self.value())
            if self.value() == 'US':
                return MyModel.objects.language('en-us')
            elif self.value() == 'Brazil':
                return MyModel.objects.language('pt-br')
            elif self.value() == 'En':
                return MyModel.objects.language('en')
            elif self.value() == 'De':
                return MyModel.objects.language('de')
            elif self.value() == 'Pt':
                return MyModel.objects.language('pt')
            elif self.value() == 'Fr':
                return MyModel.objects.language('fr')
            elif self.value() == 'Es':
                return MyModel.objects.language('es')
            else:
                return queryset
        else:
            return queryset


class MyModelAdmin(HvadAdmin):
    list_display = ['get_description', 'all_translations']
    list_filter = (LangCountryFilter, )
    # ...

@spectras
Copy link
Collaborator

spectras commented Jul 6, 2016

It's a clever solution. I think you could spare some code by using Django settings. Assuming the list of language is that of your website, you could do:

from django.conf import settings

class LangCountryFilter(SimpleListFilter):
    title = 'country' 
    parameter_name = 'country'

    def lookups(self, request, model_admin):
        return settings.LANGUAGES

    def queryset(self, request, queryset):
        language = self.value()
        if language:
            queryset = MyModel.objects.language(language)
        return queryset

Note however that this filter will discard any previously applied filter when there is a language defined, because it recreates the queryset from scratch. I don't really have a solution for this atm.
When you upgrade to Django 1.9, you can replace the queryset line with queryset = queryset.language(langauge) to avoid this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants