Evgenii Legotckoi
Evgenii LegotckoiМаусым 1, 2022, 4:30 Т.Ж.

Django - Сабақ 059. Таңдалған тілді пайдаланушы параметрлерінде сақтау

Бұл мақалада мен пайдаланушы сайттағы тілдер арасында ауыса алатындай етіп сайтта сілтеме жасаудың мысалын көрсеткім келеді.

Бірақ мен бұл функцияның жетілдірілген нұсқасын көрсетемін, атап айтқанда таңдалған тілді пайдаланушы кестесінде сақтау, сондай-ақ пайдаланушыны пайдаланушы таңдаған дұрыс тілі бар бетке қайта бағыттау, егер олар әрине рұқсат етілген болса. Яғни, егер пайдаланушы неміс тілін өзі үшін орнатқан болса, онда ағылшын тіліндегі сілтеме арқылы сайтқа кіргенде, сайт пайдаланушыны неміс тілі бар бетке автоматты түрде қайта бағыттайды.

Ол үшін пайдаланушы үлгісіне тіл коды өрісін қосу керек, әркім әдепкі емес Django-да өзінің пайдаланушы үлгісін пайдаланып жатыр деп үміттенемін.
Стандартты Django тілін орнату функциясын қайта жазыңыз, сондай-ақ тораптан сұралған URL мекенжайларын өңдейтін орта бағдарламалық құралды қосыңыз.

Басқа нәрселермен қатар, бұл функция тіркелген пайдаланушылар үшін дұрыс тілде әріптер жасау үшін пайдалы болады.

Бұл мақала Django 4 нұсқасына негізделген және Django ескі нұсқаларына сәйкес келмеуі мүмкін.

Пайдаланушы үлгісін орнату

Таңдалған тілдің коды қосылатын пайдаланушы үлгісіне тіл өрісін қосамыз, әдепкі бойынша ол сіздің сайтыңыздың негізгі тілі болып табылатын тіл болады.

Файл 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)

Тиісінше, біз көші-қонды жасап, оны орындаймыз.

python manage.py makemigrations
python manage.py migrate

Тілді орнату үшін көрініс қосыңыз

Файл yourapp/yorauthapp/views.py

Мұнда екі маңызды тармақ бар:

  • Бастапқы функция пішінді пайдалану және POST хабарламасын жіберу болып табылады. Мен тіл коды бар сілтемені қалаймын.
  • Пайдаланушы рұқсат етілген жағдайда,
# -*- 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

Негізгі urls.py файлыңызға set_language қосыңыз

Енді үлгілердегі тілді ауыстыруға арналған сілтемелерді жасау үшін көріністі қосу керек.

# -*- coding: utf-8 -*-

from django.urls import path

from yourauthapp import views


urlpatterns = [
    path('lang/<str:lang_code>/', views.set_language, name='lang'),
    ...
]

Үлгідегі сілтемелерді құру

Пайдаланушы тілді ауыстыруды таңдаған бастапқы бетке дұрыс бағыттауды алу үшін сілтемеге ?next={{ request.path }} қосатынымды ескеріңіз.

{% 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 %}

қолданбаңыз/yourauthapp/middleware.py

Ал енді пайдаланушыны автоматты түрде сәйкес тілі бар бетке қайта бағыттайтын аралық бағдарламаны жазайық.

# -*- 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

Бұл сайт параметрлерінде аралық бағдарламаны қосу үшін ғана қалады және бәрі жұмыс істейді.

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',
]

Қорытынды

Енді барлық рұқсат етілген пайдаланушылар әрқашан таңдаған тілі бар беттерге қайта бағытталады.

Әрине, рұқсат етілмеген пайдаланушылар үшін бұл жұмыс істемейді, бірақ кем дегенде олар әрқашан сіздің сайтыңызда қол жетімді тілдің ішінен өздері қалаған тілді таңдай алады.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

IscanderChe
  • Маусым 1, 2022, 4:54 Т.Ж.

Добрый день.

Помимо прочего, данный функционал будет полезен для того, чтобы формировать письма с правильным языком для зарегистрированных пользователей.

Уведомление об этой статье на почту мне пришло почему-то на английском.

Evgenii Legotckoi
  • Маусым 1, 2022, 5:57 Т.Ж.
  • (өңделген)

Добрый день!
Потому что на этом сайте это не сделано :)
Я сейчас работаю над вторым проектом и делаю работу над ошибками :)
Позже буду ремонтировать и здесь, нужно ещё на более новую версию Django мигрировать.

Владислав Меленчук
  • Маусым 4, 2022, 3:42 Т.Ж.

Будет интересно посмотреть ваш новый проект, Евгений. Уж как никак, но ваши статьи самые лучшие и подходят на уровень детального создания, ведь по вашим статьям я делал много для своего проекта. Надеюсь у вас будут перспективы создать инструкции с новыми вашими познаниями и новым кодом :)

Evgenii Legotckoi
  • Маусым 4, 2022, 7:07 Т.Ж.

Благодарю за отзыв. Да, я понемногу буду писать статьи с информацией из нового проекта.
А сам проект позже анонсирую, также повешаю в сайдбаре анонсовый виджет.

Владислав Меленчук
  • Маусым 5, 2022, 2:56 Т.Ж.

Буду ждать, Евгений! Потому что буду разрабатывать новый проект, как альманах программиста новичка.)

NSProject
  • Маусым 5, 2022, 6:47 Т.Ж.

Можно пояснительную записку настроек. Что примерно указывается

                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,
Evgenii Legotckoi
  • Маусым 6, 2022, 6:18 Т.Ж.

Это всё настройки для языка в Django, по умолчанию ничего менять не нужно.
А сам этот кусок кода скопирован из оригинальной функции.

Подробнее написано в официальной документации Django settings .
Там написаны и значения по умолчанию.

NSProject
  • Маусым 6, 2022, 10:57 Т.Ж.

Я как так сказать новичёк в Python и Django в целом. Читал документацию и вот по этому мне показалось сразу что это оттуда. Немного маштабируемо по своему усмотрению. Однако все настройки из settings возможно индивидуальны. Это как я понимаю те настройки что я делаю сам.

Evgenii Legotckoi
  • Маусым 7, 2022, 3:06 Т.Ж.

Да, вы можете в своём settings файле определить все эти переменные и значения по умолчанию будут переписаны.

c
  • Жел. 1, 2023, 5:34 Т.Қ.

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

Evgenii Legotckoi
  • Жел. 3, 2023, 8:39 Т.Ж.

It is redirect from untranslated url to translated url. It is normal behavior for mutlilanguage web site based on the Django.

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз