Utilizando Python kwargs (keyword arguments) en Flask url_for() para paginación
Python kwargs es una forma fácil de pasar datos a una función. Usando el doble asterisco para desempaquetar podemos pasar estos datos a otra función.
Para este sitio web estoy utilizando Flask y SQLAlchemy sin la extensión Flask-SQLAlchemy . Necesito paginación para varias páginas. Por ejemplo, la página de inicio contiene la lista de blogs y debe mostrar un máximo de 12 elementos por página. No es tan difícil de aplicar. La función de vista de página de inicio requiere un número page_number que por defecto es 1 si no se especifica:
@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)
y parte de la clase de paginación:
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)),
}
Nada especial, funciona bien, algunas urls generadas por url_for(), cuando el lenguaje es'en':
http:127.0.0.1:8000/en/
http:127.0.0.1:8000/en/2
Tenga en cuenta que Flask busca el punto final y utiliza el valor del argumento nombrado.
Parámetros de URL multinivel
En la parte de administración de la aplicación hay una entrada donde puedo editar los idiomas. Los registros de idioma se agrupan en una versión de idioma. Las versiones de idioma pueden ser listadas, una nueva versión de idioma puede ser creada a partir de una versión de idioma existente, editada y activada. Este esquema también permite cambiar de idioma sobre la marcha, es decir, sin reiniciar la aplicación.
El primer paso es seleccionar el idioma. Esto presentará una lista de idiomas que pueden ser editados. Como todas las listas, la lista de idiomas está paginada.
Al igual que la función de vista de página de inicio anterior, la función de vista de lista de idiomas se llama con un número de página. Para indicar la versión de idioma, también se llama la función de lista de idiomas con el 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)
...
Tenga en cuenta que la función pagination.set_params() ahora tiene un parámetro adicional (nombre): language_version_id. Esto debe agregarse a la url de paginación, para que se vean así:
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
Aquí 5 es el language_version_id y el siguiente número es el número de página.
Kwargs (keyword arguments) al rescate
No he hecho mucho especial con kwargs hasta ahora, pero en este caso resulta extremadamente útil. Utilizando kwargs podemos tener un número ilimitado de keyword arguments. Aquí sólo necesito dos, pero con kwargs todo está listo para tener tres o más. Abajo es otra vez parte de la clase Paginación pero ahora con kwargs añadido:
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)),
}
En la línea def set_params(...) añadí **endpoint_kwargs. No tenemos que utilizarlo, pero está ahí cuando lo necesitamos. Luego en la función url_for() también añadí **endpoint_kwargs. La notación "**" antes del parámetro_kwargs significa que debe desembalarse el parámetro keyword arguments . Si no hay nada que desempaquetar, no hay problema. El orden de keyword arguments no es importante aquí porque están nombrados.
Resumen
Lo que al principio parecía mucho trabajo parecía ser muy fácil utilizando Python keyword arguments. Por primera vez utilicé kwargs con el doble asterisco para desempaquetar. Muy bonito.
Enlaces / créditos
What is the purpose and use of **kwargs?
https://stackoverflow.com/questions/1769403/what-is-the-purpose-and-use-of-kwargs
Leer más
Flask
Recientes
- Cómo ocultar las claves primarias de la base de datos UUID de su aplicación web
- Don't Repeat Yourself (DRY) con Jinja2
- SQLAlchemy, PostgreSQL, número máximo de filas por user
- Mostrar los valores en filtros dinámicos SQLAlchemy
- Transferencia de datos segura con cifrado de Public Key y pyNaCl
- rqlite: una alternativa de alta disponibilidad y dist distribuida SQLite
Más vistos
- Usando Python's pyOpenSSL para verificar los certificados SSL descargados de un host
- Usando UUIDs en lugar de Integer Autoincrement Primary Keys con SQLAlchemy y MariaDb
- Usando PyInstaller y Cython para crear un ejecutable de Python
- Conectarse a un servicio en un host Docker desde un contenedor Docker
- SQLAlchemy: Uso de Cascade Deletes para eliminar objetos relacionados
- Flask RESTful API validación de parámetros de solicitud con esquemas Marshmallow