angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Использование Python kwargs (keyword arguments) в Flask url_for() для страничной разбивки на страницы

Python kwargs - это простой способ передачи данных в функцию. Используя двойную звездочку для распаковки, мы можем передать эти данные в другую функцию.

24 ноября 2019
post main image
https://unsplash.com/@josephtpearson

Для этого веб-сайта я использую Flask и SQLAlchemy без расширения Flask-SQLAlchemy . Мне нужна страничка на несколько страниц. Например, домашняя страница содержит список блогов и должна показывать максимум 12 элементов на страницу. Это не так уж и сложно осуществить. Функция просмотра домашней страницы требует номер страницы_номер, который по умолчанию равен 1, если он не указан:

@pages_blueprint.route('/', defaults={'page_number': 1})
@pages_blueprint.route('/<int:page_number>')
def homepage(page_number):

    # get total items for the selected language
    total_items = content_item_query.total_items_count()

    pagination = Pagination(items_per_page=12)
    pagination.set_params(page_number, total_items, 'pages.homepage')
    ...
    return =  render_template(
        'pages/index.html', 
        page_title=page_title,
        ...
        pagination=pagination)

и часть урока пагинации:

class Pagination:
    ...
    def set_params(self, page_number, total_items, endpoint):
        ...
        # previous page
        if page_number > 1:
            previous_page_number = page_number - 1
            self.previous_page = {
                'page_number': previous_page_number,
                'url': url_for(endpoint, page_number=str(previous_page_number)),
            }

Ничего особенного, работает нормально, некоторые urls генерируются url_for(), когда языком является 'en':

http:127.0.0.1:8000/en/

http:127.0.0.1:8000/en/2

Обратите внимание, что Flask ищет конечную точку и использует значение именованного аргумента.

Многоуровневые параметры url

В административной части приложения есть запись, где я могу редактировать языки. Языковые записи сгруппированы в языковую версию. Языковые версии могут быть перечислены, новая языковая версия может быть создана из существующей языковой версии, отредактирована и активирована. Эта схема также позволяет менять языки на лету, т.е. без перезапуска приложения.

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

@admin_language_blueprint.route('/languages/list/<int:language_version_id>/<int:page_number>')
@admin_language_blueprint.route('/languages/list/<int:language_version_id>', defaults={'page_number': 1})
@login_required
@requires_user_roles('language_admin')
def languages_list(language_version_id, page_number):

    # get total items
    total_items = len(all_languages)

    pagination = Pagination(items_per_page=6)
    pagination.set_params(page_number, total_languages, 'admin_language.languages_list', language_version_id=language_version_id)
    ...

Обратите внимание, что функция pagination.set_params() теперь имеет дополнительный параметр (name): language_version_id. Это должно быть добавлено к мочеиспускательной урне, чтобы они выглядели так:

http://127.0.0.1:8000/admin/en/language/languages/list/5

http://127.0.0.1:8000/admin/en/language/languages/list/5/1

http://127.0.0.1:8000/admin/en/language/languages/list/5/2

Здесь 5 - language_version_id, а следующее число - номер страницы.

Kwargs (keyword arguments) на спасательную операцию

До сих пор я не делал ничего особенного с kwargs , но в этом случае он оказался чрезвычайно полезным. Используя kwargs , мы можем иметь неограниченное количество keyword arguments. Здесь мне нужно только два, но с kwargs все готово, чтобы их было три и более. Ниже снова находится часть класса Pagination, но теперь с добавлением kwargs :

class Pagination:
    ...
    def set_params(self, page_number, total_items, endpoint, **endpoint_kwargs):
        ...
        # previous page
        if page_number > 1:
            previous_page_number = page_number - 1
            self.previous_page = {
                'page_number': previous_page_number,
                'url': url_for(endpoint, **endpoint_kwargs, page_number=str(previous_page_number)),
            }

В строке set_params(...) по умолчанию я добавил **endpoint_kwargs. Мы не обязаны использовать его, но он есть, когда он нам нужен. Затем в функцию url_for() я также добавил **endpoint_kwargs. Символ '**' перед конечной точкой_kwargs означает, что keyword arguments должен быть распакован. Если распаковать вещи нечего, то проблем нет. Порядок keyword arguments здесь не важен, потому что они названы.

Резюме

То, что казалось большим объемом работы вначале, оказалось очень простым с помощью Python keyword arguments. Впервые я использовал kwargs с двойной звездочкой для распаковки. Очень мило.

Ссылки / кредиты

What is the purpose and use of **kwargs?
https://stackoverflow.com/questions/1769403/what-is-the-purpose-and-use-of-kwargs

Подробнее

Flask

Оставить комментарий

Комментируйте анонимно или войдите в систему, чтобы прокомментировать.

Комментарии

Оставьте ответ

Ответьте анонимно или войдите в систему, чтобы ответить.