Django中使用Paginator的页面filter标签翻译失效问题求助
Great question! Django's Paginator itself doesn't cause translation failures with django-filters, but the way you're combining them in your code could indirectly trigger issues with translation context. Let's break down the most likely causes and fixes based on your code:
1. Code Execution Order (Most Likely Culprit)
Looking at your coordinator_students view, you're initializing the StudentFilter before calling get_standard_context(FSJ_user). If get_standard_context handles activating the user's preferred language (e.g., calling activate(FSJ_user.lang_pref)), the filter's labels (which rely on gettext_lazy from your model's verbose_name) might resolve to the default language before the user's language is activated.
Even though gettext_lazy is supposed to be evaluated at render time, django-filters does some internal setup when initializing the FilterSet that could lock in the default language if the context isn't set up yet.
Fix: Reorder your code to activate the language first, then initialize the filter:
def coordinator_students(request): FSJ_user = get_FSJ_user(request.user.username) # First set up context to ensure language is activated context = get_standard_context(FSJ_user) student_list = Student.objects.all().order_by('ccid') # Now initialize the filter with the correct language context filtered_list = StudentFilter(request.GET, queryset=student_list) student_paginator = Paginator(filtered_list.qs, 25) template = loader.get_template("FSJ/coord_student_list.html") context["student_list"] = student_list page = request.GET.get('page', 1) try: students = student_paginator.page(page) except PageNotAnInteger: students = student_paginator.page(1) except EmptyPage: students = student_paginator.page(student_paginator.num_pages) context["filter"] = filtered_list context["students"] = students return HttpResponse(template.render(context, request))
2. Custom Locale Middleware for User Language Preference
If your get_standard_context doesn't handle language activation, and you're relying on Django's default LocaleMiddleware, it might not be reading the lang_pref field from your FSJUser model. The default middleware looks for a lang field on the user model, not lang_pref.
Fix: Create a custom middleware to use your user's lang_pref:
# your_app/middleware.py from django.middleware.locale import LocaleMiddleware from django.conf import settings class FSJLocaleMiddleware(LocaleMiddleware): def process_request(self, request): # Check if user is authenticated and has an FSJUser if request.user.is_authenticated: try: fsj_user = request.user.fsjuser # Set the session language to the user's preference request.session[settings.LANGUAGE_SESSION_KEY] = fsj_user.lang_pref except FSJUser.DoesNotExist: pass # Call the parent class's process_request to handle other language sources super().process_request(request)
Then update your settings.py to use this middleware instead of the default:
MIDDLEWARE = [ # ... other middleware (keep SessionMiddleware and AuthenticationMiddleware before this) 'django.contrib.auth.middleware.AuthenticationMiddleware', 'your_app.middleware.FSJLocaleMiddleware', # Replace default LocaleMiddleware # ... other middleware ]
3. Verify Template Rendering of Filter Form
Ensure your template is rendering the filter form correctly, without overriding the translated labels. For example, use the standard django-filters form rendering:
{# coord_student_list.html #} <form method="get"> {{ filter.form.as_p }} <button type="submit">{% trans "Filter" %}</button> </form>
Avoid hardcoding labels in the template, as this bypasses the gettext_lazy translations from your model.
4. Double-Check Translation Files
Even though you've checked this, run django-admin makemessages -l fr (replace fr with your target language) to regenerate translation files, and confirm all filter labels (like "CCID", "First Name") are present and correctly translated in the .po files. Don't forget to compile the translations with django-admin compilemessages.
内容的提问来源于stack exchange,提问作者lucky3

