In diesem Artikel möchte ich ein Beispiel zeigen, wie Sie einen Link auf der Website erstellen können, damit der Benutzer zwischen den Sprachen auf der Website wechseln kann.
Ich werde jedoch eine erweiterte Version dieser Funktionalität zeigen, nämlich das Speichern der ausgewählten Sprache in der Benutzertabelle sowie das Umleiten des Benutzers auf eine Seite mit der richtigen Sprache, die vom Benutzer ausgewählt wurde, sofern er natürlich berechtigt ist. Das heißt, wenn der Benutzer die deutsche Sprache für sich selbst eingestellt hat, leitet die Website den Benutzer beim Aufrufen der Website über einen englischen Link automatisch auf die Seite mit der deutschen Sprache weiter.
Dazu müssen wir dem Benutzermodell ein Sprachcodefeld hinzufügen. Ich hoffe, dass jeder bereits sein Benutzermodell in Django verwendet, anstatt das Standardmodell.
Schreiben Sie die standardmäßige Django-Spracheinrichtungsfunktion neu und fügen Sie auch eine Middleware hinzu, die die von der Website angeforderten URLs verarbeitet.
Diese Funktionalität wird unter anderem nützlich sein, um für registrierte Benutzer Briefe mit der richtigen Sprache zu generieren.
Dieser Artikel basiert auf Django 4 und ist möglicherweise nicht für ältere Versionen von Django geeignet.
Richten Sie das Benutzermodell ein
Fügen wir dem Benutzermodell das Sprachfeld hinzu, in dem der Code der ausgewählten Sprache hinzugefügt wird. Standardmäßig ist dies die Sprache, die die Hauptsprache für Ihre Website ist.
Файл yourapp/yourauthapp/models.py
# -*- coding: utf-8 -*- from django.conf import settings from django.contrib.auth.models import AbstractUser from django.db import models class Group(DjangoGroup): class Meta: proxy = True class User(AbstractUser): language = models.CharField(max_length=10, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)
Dementsprechend werden wir eine Migration erstellen und ausführen.
python manage.py makemigrations python manage.py migrate
Fügen Sie eine Ansicht hinzu, um die Sprache einzustellen
Файл yourapp/yourauthapp/views.py
Hier gibt es zwei wichtige Punkte:
- Die ursprüngliche Funktion besteht darin, ein Formular zu verwenden und eine POST-Nachricht zu senden. Ich bevorzuge den Link mit dem Sprachcode.
- Falls der Benutzer autorisiert ist,
# -*- coding: utf-8 -*- from django.conf import settings from django.http import HttpResponseRedirect, HttpResponse from django.urls import translate_url from django.utils.http import url_has_allowed_host_and_scheme from django.utils.translation import check_for_language def set_language(request, lang_code): next_url = request.POST.get('next', request.GET.get('next')) if ( (next_url or request.accepts('text/html')) and not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ) ): next_url = request.META.get('HTTP_REFERER') if not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): next_url = '/' response = HttpResponseRedirect(next_url) if next_url else HttpResponse(status=204) if request.method == 'GET': # Change method from POST to GET, we want use url parameters for this funcionality if lang_code and check_for_language(lang_code): if next_url: next_trans = translate_url(next_url, lang_code) if next_trans != next_url: response = HttpResponseRedirect(next_trans) response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, secure=settings.LANGUAGE_COOKIE_SECURE, httponly=settings.LANGUAGE_COOKIE_HTTPONLY, samesite=settings.LANGUAGE_COOKIE_SAMESITE, ) # Important part of code, set language to user, if user is authenticated if request.user.is_authenticated: request.user.language = lang_code request.user.save(update_fields=['language']) return response
set_language in Ihre Hauptdatei urls.py aufnehmen
Jetzt müssen Sie die Ansicht verbinden, damit Sie Links zum Umschalten der Sprache in Vorlagen generieren können.
# -*- coding: utf-8 -*- from django.urls import path from yourauthapp import views urlpatterns = [ path('lang/<str:lang_code>/', views.set_language, name='lang'), ... ]
Generierung von Links in der Vorlage
Beachten Sie, dass ich dem Link ?next={{ request.path }} hinzufüge, um die korrekte Weiterleitung zur ursprünglichen Seite zu erhalten, auf der der Benutzer die Sprache umgeschaltet hat.
{% get_available_languages as LANGUAGES %} {% get_language_info_list for LANGUAGES as languages %} {% for language in languages %} <a href="{% url 'lang' language.code %}?next={{ request.path }}">{{ language.name_local }}</a> {% endfor %}
yourapp/yourauthapp/middleware.py
Und jetzt schreiben wir eine Middleware, die den Benutzer automatisch auf eine Seite mit der entsprechenden Sprache umleitet.
# -*- coding: utf-8 -*- from django.http import HttpResponseRedirect from django.urls import translate_url from django.utils import translation from django.utils.deprecation import MiddlewareMixin class LocaleMiddleware(MiddlewareMixin): def process_response(self, request, response): user = getattr(request, 'user', None) if not user: return response if not user.is_authenticated: return response user_language = getattr(user, 'language', None) if not user_language: return response next_trans = translate_url(request.path, user_language) if next_trans != request.path: translation.activate(user_language) response = HttpResponseRedirect(next_trans) return response
Es bleibt nur, Middleware in den Site-Einstellungen zu aktivieren, und alles wird funktionieren.
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # add your middleware for redirect user 'yourauthapp.middleware.LocaleMiddleware', ]
Fazit
Jetzt werden alle autorisierten Benutzer immer auf Seiten mit der von ihnen gewählten Sprache umgeleitet.
Für nicht autorisierte Benutzer funktioniert dies natürlich nicht, aber zumindest können sie immer die gewünschte Sprache aus den auf Ihrer Website verfügbaren auswählen.
Добрый день.
Уведомление об этой статье на почту мне пришло почему-то на английском.
Добрый день!
Потому что на этом сайте это не сделано :)
Я сейчас работаю над вторым проектом и делаю работу над ошибками :)
Позже буду ремонтировать и здесь, нужно ещё на более новую версию Django мигрировать.
Будет интересно посмотреть ваш новый проект, Евгений. Уж как никак, но ваши статьи самые лучшие и подходят на уровень детального создания, ведь по вашим статьям я делал много для своего проекта. Надеюсь у вас будут перспективы создать инструкции с новыми вашими познаниями и новым кодом :)
Благодарю за отзыв. Да, я понемногу буду писать статьи с информацией из нового проекта.
А сам проект позже анонсирую, также повешаю в сайдбаре анонсовый виджет.
Буду ждать, Евгений! Потому что буду разрабатывать новый проект, как альманах программиста новичка.)
Можно пояснительную записку настроек. Что примерно указывается
Это всё настройки для языка в Django, по умолчанию ничего менять не нужно.
А сам этот кусок кода скопирован из оригинальной функции.
Подробнее написано в официальной документации Django settings .
Там написаны и значения по умолчанию.
Я как так сказать новичёк в Python и Django в целом. Читал документацию и вот по этому мне показалось сразу что это оттуда. Немного маштабируемо по своему усмотрению. Однако все настройки из settings возможно индивидуальны. Это как я понимаю те настройки что я делаю сам.
Да, вы можете в своём settings файле определить все эти переменные и значения по умолчанию будут переписаны.
It tries to do language translation in API views. That's why it sends or receives the same API request twice. Do you have any suggestions on this? Example: stripe webhook.
"GET /warehouse/webhook/ HTTP/1.1" 302
"GET /en/warehouse/webhook/ HTTP/1.1" 200
It is redirect from untranslated url to translated url. It is normal behavior for mutlilanguage web site based on the Django.