Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

7.5 Шаблоны URL-адресов для интернационализации
3 из 3 шагов пройдено

Перевод шаблонов URL-адресов


Django поддерживает переведенные строковые литералы в шаблонах URL-адресов. В одном шаблоне URL-адреса можно использовать перевод на каждый язык. Шаблоны URL-адресов можно помечать для перевода так же, как и строковые литералы, используя функцию gettext_lazy().

Отредактируйте файл urls.py приложения books, добавив переводные строковые литералы в шаблоны URL-адресов, как показано ниже:

from django.urls import path
from .views import book_list, create_book, update_book_details, book_detail, delete_book, update_book_status, \
    book_list_sort
from django.utils.translation import gettext_lazy as _

urlpatterns = [
    path("", book_list, name="book_list"),
    path(_("create_book/"), create_book, name="create_book"),
    path(_("update_book_details/<int:pk>/"), update_book_details, name="update_book_details"),
    path(_("book_detail/<int:pk>/"), book_detail, name="book_detail"),
    path(_("delete_book/<int:pk>/"), delete_book, name="delete_book"),
    path(_("update_book_status/<int:pk>/"), update_book_status, name="update_book_status"),
    path(_("book_list_sort/<filter>/<direction>/"), book_list_sort, name="book_list_sort"),
]


Затем отредактируем функцию сортировки book_list_sort() в файле views.py приложения books:

from django.utils.translation import gettext_lazy as _

# ...

@require_http_methods(['GET'])
def book_list_sort(request, filter, direction):
    filter_dict = {_('id'): 'pk',
                   _('title'): 'title',
                   _('author'): 'author',
                   _('price'): 'price',
                   _('read'): 'read'}

    if filter in filter_dict:
        if direction == _('ascend'):
            book_list = Book.objects.order_by(filter_dict[filter])
        else:
            book_list = Book.objects.order_by('-' + filter_dict[filter])
    else:
        book_list = Book.objects.all()

    return render(request, 'partial_book_list.html', {'book_list': book_list})


И далее файл шаблонов base.html, добавим к переводу строковые литералы значений фильтра, направления сортировки, классов *-ascend и *-descend(это необходимо для корректной работы функции блокировки нажатой кнопки).

Примечание: обратите внимание, что теперь в htmx-атрибутах адресов запроса, в значениях filter и direction используются вместо строк - переменные с соответствующими именами, не забудьте удалить кавычки.

</head>

<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>

    <div class="container">
        <div class="row mt-5">
            <div class="col">
                <!-- Форма для добавления новой книги -->
                {% include "partial_create_book_form.html" %}

                <!-- Таблица книг -->
                <form class="form-inline">
                <table class="table table-bordered table-sm mt-5">
                    {% trans "id" as id %}{% trans "title" as title %}
                    {% trans "author" as author %}{% trans "price" as price %}
                    {% trans "read" as read %}{% trans "ascend" as ascend %}
                    {% trans "descend" as descend %}
                    <thead>
                        <tr>
                            <!-- Заголовки столбцов таблицы -->

                            <!-- Заголовок номера книги -->
                            <th scope="col" style="width: 10%" class="text-center">
                                <small>
                                    {% trans "No." %}
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=id direction=ascend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-down-square ms-1 {% trans 'id-ascend' %} disabled-button"></i>
                                    </a>
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=id direction=descend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-up-square {% trans 'id-descend' %}"></i>
                                    </a>
                                </small>
                            </th>

                            <!-- Заголовок названия книги -->
                            <th scope="col" style="width: 26%" class="text-center">
                                <small>
                                    {% trans "Title" %}
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=title direction=ascend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-down-square ms-1 {% trans 'title-ascend' %}"></i>
                                    </a>
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=title direction=descend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-up-square {% trans 'title-descend' %}"></i>
                                    </a>
                                </small>
                            </th>

                            <!-- Заголовок автора книги -->
                            <th scope="col" style="width: 26%" class="text-center">
                                <small>
                                    {% trans "Author" %}
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=author direction=ascend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-down-square ms-1 {% trans 'author-ascend' %}"></i>
                                    </a>
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=author direction=descend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-up-square {% trans 'author-descend' %}"></i>
                                    </a>
                                </small>
                            </th>

                            <!-- Заголовок цены книги -->
                            <th scope="col" style="width: 11%" class="text-center">
                                <small>
                                    {% trans "Price ($)" %}
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=price direction=ascend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-down-square ms-1 {% trans 'price-ascend' %}"></i>
                                    </a>
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=price direction=descend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-up-square {% trans 'price-descend' %}"></i>
                                    </a>
                                </small>
                            </th>

                            <!-- Заголовок статуса книги -->
                            <th scope="col" style="width: 11%" class="text-center">
                                <small>
                                    {% trans "Status" %}
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=read direction=descend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-down-square ms-1 {% trans 'read-descend' %}"></i>
                                    </a>
                                    <a href=""
                                       hx-get="{% url 'book_list_sort' filter=read direction=ascend %}"
                                       hx-target="#book-list"
                                       hx-swap="innerHTML" >
                                        <i class="table-icon bi bi-arrow-up-square {% trans 'read-ascend' %}"></i>
                                    </a>
                                </small>
                            </th>


Там-же доработаем наш JavaScript-код, что-бы он корректно работал с переведёнными URL-адресами:

    <script>
        function cngElementsAtr(cls, atr, val){
            var elems = document.getElementsByClassName(cls);
            for(var i = 0; i < elems.length; i++) {
                elems[i][atr] = val;
            }
        }
        document.body.addEventListener('htmx:afterRequest', (event) => {
            path_str = decodeURI(event.detail.pathInfo.requestPath);
            if(path_str.includes("{% trans 'create_book' %}")){
                cngElementsAtr('clrtxt', 'value', '');
            }else if(path_str.includes("{% trans 'update_book_details' %}")){
                if(event.detail.requestConfig.verb === 'put'){
                    cngElementsAtr('disbtn', 'disabled', true);
                }else{
                    cngElementsAtr('disbtn', 'disabled', false);
                }
            }else if(path_str.includes("{% trans 'book_detail' %}")){
                cngElementsAtr('disbtn', 'disabled', false);
            }else if(path_str.includes("{% trans 'book_list_sort' %}")){
                path_arr = path_str.split('/');
                path_arr.pop()
                curr_class = path_arr.pop()
                curr_class = path_arr.pop() + '-' + curr_class
                document.getElementsByClassName('disabled-button')[0].classList.remove('disabled-button');
                document.getElementsByClassName(curr_class)[0].classList.add('disabled-button');
            }
        });
    </script>

Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий
Нет обсуждений. Начните первое.