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

Gebruik van Python kwargs (trefwoord argumenten) in Flask url_for() voor paginering

Python kwargs is een eenvoudige manier om gegevens door te geven aan een functie. Met behulp van het dubbele sterretje voor het uitpakken kunnen we deze gegevens doorgeven aan een andere functie.

24 november 2019 Bijgewerkt 25 november 2019
post main image
https://unsplash.com/@josephtpearson

Voor deze website gebruik ik Flask en SQLAlchemy zonder de Flask-SQLAlchemy uitbreiding. Ik heb paginering nodig voor meerdere pagina's. Op de homepage staat bijvoorbeeld de lijst met blogs en er mogen maximaal 12 items per pagina op staan. Het is niet zo moeilijk uit te voeren. De home page view functie vereist een page_nummer dat standaard op 1 staat als het niet gespecificeerd is:

@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)

en een deel van de Pagination klasse:

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)),
            }

Niets bijzonders, werkt prima, sommige urls gegenereerd door url_for(), wanneer de taal 'en' is:

http:127.0.0.1:8000/en/

http:127.0.0.1:8000/en/2

Merk op dat Flask het eindpunt opzoekt en de waarde van het genoemde argument gebruikt.

Multilevel url parameters

In het admin gedeelte van de applicatie is er een vermelding waar ik de talen kan bewerken. Taalrecords worden gegroepeerd in een taalversie. Er kunnen taalversies worden opgesomd, een nieuwe taalversie kan worden aangemaakt op basis van een bestaande taalversie, bewerkt en geactiveerd. Deze regeling maakt het ook mogelijk om tijdens de vlucht van taal te veranderen, d.w.z. zonder de toepassing opnieuw te starten.

De eerste stap is het selecteren van de taalversie. Dit geeft een lijst van talen die kunnen worden bewerkt. Zoals alle lijsten is de lijst van talen gepagineerd.
Net als de functie voor het bekijken van de startpagina hierboven, wordt de functie voor het bekijken van de talenlijst opgeroepen met een paginanummer. Om de taalversie aan te geven, wordt de talenlijstfunctie ook opgeroepen met de 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)
    ...

Merk op dat de pagination.set_params() functie nu een extra (naam) parameter heeft: language_version_id. Dit moet worden toegevoegd aan de pagina-url, zodat ze er zo uit zullen zien:

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

Hier is 5 de language_version_id en het volgende nummer is het paginanummer.

Kwargs (trefwoordargumenten) om de redding te bewerkstelligen

Ik heb tot nu toe niet veel speciaals gedaan met kwargs , maar in dit geval is het zeer nuttig. Met behulp van kwargs kunnen we een onbeperkt aantal trefwoord argumenten hebben. Hier heb ik er maar twee nodig, maar met kwargs is alles aanwezig om er drie of meer te hebben. Hieronder is weer onderdeel van de Pagination class maar nu met kwargs toegevoegd:

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)),
            }

In de regel def set_params(....) heb ik **endpoint_kwargs toegevoegd. We hoeven het niet te gebruiken, maar het is er wel wanneer we het nodig hebben. Vervolgens heb ik in de url_for() functie ook **endpoint_kwargs toegevoegd. De '**' voor endpoint_kwargs notatie betekent dat de argumenten van het trefwoord uitgepakt moeten worden. Als er niets uit te pakken is, dan is er geen probleem. De volgorde van de trefwoordargumenten is hier niet van belang omdat ze een naam hebben.

Samenvatting

Wat in het begin veel werk leek te zijn, bleek zeer eenvoudig te zijn met behulp van Python trefwoordargumenten. Voor het eerst heb ik kwargs met een dubbel sterretje gebruikt om uit te pakken. Heel mooi.

Links / credits

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

Lees meer

Flask

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.