


Création d'une application To-Do avec HTMX et Django, partie défilement infini
Il s'agit de la partie 7 de la série dans laquelle je documente mon processus d'apprentissage de HTMX avec Django, dans laquelle nous suivrons la documentation de HTMX pour implémenter une fonctionnalité de défilement infini pour les éléments à faire.
Si vous souhaitez consulter le reste de la série, jetez un œil à dev.to/rodbv pour la liste complète.
Mise à jour du modèle partiel pour charger plusieurs éléments
Lorsque nous implémenterons le défilement infini, nous devrons renvoyer plusieurs éléments de tâche (la prochaine "page" d'éléments) et les charger dans le modèle partiel que nous avons actuellement. Cela signifie changer un peu la façon dont notre modèle partiel est composé ; il est actuellement défini comme décrit dans le diagramme ci-dessous, dans lequel le modèle partiel est responsable du rendu d'un seul élément de tâche :
Nous voulons inverser l'ordre, en ayant le partiel autour de la boucle for :
Effectuons l'échange dans le modèle core/templates/index.html :
Soon we will get back to the template to add the hx-get ... hx-trigger="revealed" bit that performs the infinite scroll, but first let's just change the view to return several items instead of one on the toggle and create operations:
... previous code def _create_todo(request): title = request.POST.get("title") if not title: raise ValueError("Title is required") todo = Todo.objects.create(title=title, user=request.user) return render( request, "tasks.html#todo-items-partial", # <p>Les tests vérifiant le contenu réussissent toujours et la page a le même aspect, nous sommes donc prêts à implémenter le défilement infini lui-même.</p> <h2> Implémentation du défilement infini </h2> <p>Sur le modèle, nous devons configurer une requête hx-get vers /tasks, avec hx-trigger="revealed", ce qui signifie que la requête GET n'est déclenchée que lorsque l'élément est sur le point d'entrer et devient visible à l'écran ; cela signifie que nous voulons qu'il soit défini après le dernier élément de la liste, et nous devons également indiquer quelle "page" de données nous voulons charger. Dans notre cas, nous afficherons 20 éléments à la fois.</p> <p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173613850692024.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Creating a To-Do app with HTMX and Django, part infinite scroll"></p> <p>Modifions le modèle en conséquence :<br> </p> <pre class="brush:php;toolbar:false">
- s we get from the server, which is great because not only we show the new data we got, but we also get rid of the loading icon.
We can now move to the views file.
As a recap, here's how the GET /tasks view looks like by now; it's always returning the full template.
@require_http_methods(["GET", "POST"]) @login_required def tasks(request): if request.method == "POST": return _create_todo(request) # GET /tasks context = { "todos": request.user.todos.all().order_by("-created_at"), "fullname": request.user.get_full_name() or request.user.username, } return render(request, "tasks.html", context)
Il y a déjà un changement effectué dans le code ci-dessus, qui consiste à trier d'abord par tâches les plus récentes ; maintenant que nous nous attendons à avoir une longue liste, cela n'a pas de sens d'ajouter de nouveaux éléments en bas et de les mélanger avec un défilement infini - le nouvel élément finira par être mélangé au milieu de la liste.
Nous devons maintenant différencier les requêtes GET régulières des requêtes HTMX, pour lesquelles nous renverrons simplement une liste de tâches et notre modèle partiel. Il existe une bibliothèque appelée django-htmx qui est très pratique, car elle étend le paramètre request avec des attributs comme request.htmx et les valeurs de tous les attributs hx-*, mais c'est exagéré pour le moment ; Vérifions simplement l'en-tête HTMX maintenant et gérons la pagination à l'aide du paginateur de Django.
# core/views.py ... previous code PAGE_SIZE = 20 ...previous code @require_http_methods(["GET", "POST"]) @login_required def tasks(request): if request.method == "POST": return _create_todo(request) page_number = int(request.GET.get("page", 1)) all_todos = request.user.todos.all().order_by("-created_at") paginator = Paginator(all_todos, PAGE_SIZE) curr_page = paginator.get_page(page_number) context = { "todos": curr_page.object_list, "fullname": request.user.get_full_name() or request.user.username, "next_page_number": page_number + 1 if curr_page.has_next() else None, } template_name = "tasks.html" if "HX-Request" in request.headers: template_name += "#todo-items-partial" return render(request, template_name, context)
La première chose que nous faisons est de vérifier le paramètre de la page et de le définir sur 1 s'il n'est pas présent.
Nous vérifions l'en-tête HX-Request dans la requête, qui nous informera si la requête entrante provient de HTMX et nous permettra de renvoyer le modèle partiel ou le modèle complet en conséquence.
Ce code nécessite certainement quelques tests, mais avant cela, essayons-le. Jetez un œil à l'outil réseau, comment les requêtes sont déclenchées lorsque la page défile, jusqu'à ce que nous atteignions la dernière page. Vous pouvez également voir l'icône animée de « chargement » s'afficher pendant un bref instant ; J'ai limité la vitesse du réseau à 4G pour le rendre visible plus longtemps.
Ajout de tests
Pour conclure, nous pouvons ajouter un test pour garantir que la pagination fonctionne comme prévu
Soon we will get back to the template to add the hx-get ... hx-trigger="revealed" bit that performs the infinite scroll, but first let's just change the view to return several items instead of one on the toggle and create operations:
... previous code def _create_todo(request): title = request.POST.get("title") if not title: raise ValueError("Title is required") todo = Todo.objects.create(title=title, user=request.user) return render( request, "tasks.html#todo-items-partial", # <p>C'est tout maintenant ! C'est de loin le plus amusant que j'ai eu avec HTMX jusqu'à présent. Le code complet de cet article est ici. </p> <p>Pour le prochain article, j'envisage d'ajouter une gestion de l'état du client avec AlpineJS, ou peut-être d'ajouter une fonctionnalité de "date d'échéance". À bientôt !</p>
There's an if next_page_number check around the "loading" icon at the bottom of the list, it will have two purposes: one is to indicate when we're loading more data, but more importantly, when the loader is revealed (it appears on the visible part of the page), it will trigger the hx-get call to /tasks, passing the page number to be retrieved. The attribute next_page_number will also be provided by the context
The directive hx-swap:outerHTML indicates that we will replace the outerHTML of this element with the set of
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

SlitingyPapyThonListIsDoneUsingTheSyntaxList [Démarrage: arrêt: étape] .He'showitworks: 1) startisheindexofthefirStelementoinclude.2) stopisTheIndexoftheFirstelementsoexclude.3) StepistheincrementBetweenselans.it'susefulfactingPortationSoListShsandCanusegeg

NumpyAllowsForvariousOperations ONARRAYS: 1) BasicarithmeticLikeaddition, Soustraction, Multiplication, anddivision; 2) AdvancedOperationSuchasmatrixMultiplication; 3) Element-Wiseoperations withoutExplicitloop

ArraySinpython, en particulier ThroughNumpyandPandas, aressentialfordataanalysis, offingspeeedAfficiency.1) numpyarrayablefficienthandlingoflargedatasetsandComplexOperationsLikEMoVingAverages.2)

ListsandNumpyArraysInpythonHaveDidifferentMemoryfootprints: listsaRemoreFlexibles Butlessmemory économe, tandis que la liste de résensés est-ce qui

ToenSurepythonscriptsBeHavecorrectlyAcrossDevelopment, mise en scène et production, catégories de type: 1) EnvironmentVariblesForsImplesettings, 2) ConfigurationFilesForComplexsetups et3) dynamicloadingforadaptability.eachMethodoffersNebeneFitsAndreCeresca

La syntaxe de base pour le découpage de la liste Python est la liste [Démarrage: arrêt: étape]. 1.Start est le premier index d'élément inclus, 2.STOP est le premier indice d'élément exclu et 3.StEP détermine la taille de l'étape entre les éléments. Les tranches sont non seulement utilisées pour extraire les données, mais aussi pour modifier et inverser les listes.

ListesoutPerformarRaySin: 1) dynamicingizingandfrequentinSertions / Deletions, 2) StoringheteroGeneousData, and3) MemoryEfficiencyForsparsedata, butmayhaveslightperformanceCostSincertorations.

Toconvertapythonarraytoalist, usethelist () Constructororageneratorexpression.1) ImportTheArrayModuleandCreateArray.2) Uselist (Arr) ou [Xforxinarr] à Convertittoalist, considérant la performance et le domaine de l'émie-efficacité pour les étages.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

VSCode Windows 64 bits Télécharger
Un éditeur IDE gratuit et puissant lancé par Microsoft

Dreamweaver CS6
Outils de développement Web visuel

Dreamweaver Mac
Outils de développement Web visuel

SublimeText3 Linux nouvelle version
Dernière version de SublimeText3 Linux
