Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HTMX + Django

HTMX + Django

HTMX is a library to build interactive web applications by accessing the power of “hypertext” directly from HTML. No custom JavaScript! This talk explores the benefits of this architecture and shows how it can be applied to a Django project through simple modifications to your existing HTML templates.

Jace Browning

July 19, 2021
Tweet

More Decks by Jace Browning

Other Decks in Programming

Transcript

  1. HTMX + Django
    Jace Browning

    View Slide

  2. Outline
    ● The traditional request-response architecture
    ● Incorporating AJAX to build interactive websites
    ● Applying the “HTML over the wire” pattern using HTMX
    ● Demo

    View Slide

  3. Server-Side Applications

    View Slide

  4. https://en.wikipedia.org/wiki/File:MVC-Process.svg

    View Slide

  5. Models Views Templates

    View Slide

  6. View Slide

  7. View Slide

  8. # app/urls.py
    urlpatterns = [
    path(“items”, view.get_items, name=”items”),
    ]

    View Slide

  9. # app/views.py
    def get_items(request):
    items = Item.objects.all()
    context = {“items”: items}
    return render(request, “app/index.html”, context)

    View Slide

  10. # app/index.html
    {% include “app/_navbar.html” %}
    Items:

    {% for item in items %}

    {% include “app/_item.html” %}

    {% endfor %}

    # app/_item.html

    {{ item.name }}
    (count: {{ item.count }})

    View Slide

  11. Ideal Use Cases
    ● Largely-static content
    ● Form-based websites
    ● “CRUD” portals (think Django admin)

    View Slide

  12. Client-Side Applications (AJAX)

    View Slide

  13. https://en.wikipedia.org/wiki/File:Ajax-vergleich-en.svg

    View Slide

  14. View Slide

  15. View Slide

  16. Typical Progression
    1. Add JavaScript to existing HTML templates
    2. Pull in a component library for rendering (e.g. React)
    3. Hand over routing control to the frontend
    4. Rewrite all HTML views as JSON APIs (i.e. Django REST
    Framework viewsets)
    5. Completely extract the frontend from the backend

    View Slide

  17. Models
    Routers
    Viewsets
    Serializers
    Routers
    Redux
    Components
    Django
    Not Django
    JSON

    View Slide

  18. Ideal Use Cases
    ● Rich, dynamic websites
    ● Large teams that hire specialists
    ● Multiple, independently-deployable frontends
    ● Products with a mobile or embedded component

    View Slide

  19. Disadvantages
    ● Multiple technology stacks (2+ MVCs)
    ● State managed on the frontend and the backend
    ● Potentially duplicated business logic
    ● Backend often viewed as “second-class” to the frontend
    ● Prototyping depends on establishing a data contract

    View Slide

  20. Hybrid Applications (HTMX)

    View Slide

  21. “HTMX allows you to access AJAX,
    CSS Transitions, WebSockets and
    Server Sent Events directly in HTML,
    using attributes, so you can build
    modern user interfaces with the
    simplicity and power of hypertext.”
    https://htmx.org

    View Slide

  22. # app/base.html



    {% block content %}{% endblock content %}



    View Slide

  23. View Slide

  24. # app/index.html
    {% include “app/_navbar.html” %}
    Items:

    {% for item in items %}

    {% include “app/_item.html” %}

    {% endfor %}

    # app/_item.html

    {{ item.name }}
    (count: {{ item.count }})

    View Slide

  25. # app/_item.html

    {{ item.name }}
    (count: {{ item.count }})

    Increment on click.

    View Slide

  26. # app/_item.html
    hx-get=”{% url ‘items-update’ item.pk %}”
    hx-swap=”outerHTML”>
    {{ item.name }}
    (count: {{ item.count }})

    View Slide

  27. # app/urls.py
    urlpatterns = [
    path(“items”, view.get_items, name=”items”),
    path(“items/_update/, views.update_item, name=”items-update”),
    ]

    View Slide

  28. # app/views.py
    def get_items(request):
    items = Item.objects.all()
    context = {“items”: items}
    return render(request, “app/index.html”, context)
    def update_item(request, pk):
    item = Item.objects.get(pk=pk)
    item.count += 1
    item.save()
    context = {“item”: item}
    return render(request, “app/_item.html”, context)

    View Slide

  29. Models Views Templates
    Partial
    Partial
    Partial
    Partial
    HTML
    HTML

    View Slide

  30. Advantages
    ● All logic stays in Python!
    ● Backend is solely responsible for stage management
    ● Faster prototyping using existing HTML templates
    ● Simplified testing of partial response endpoints

    View Slide

  31. Demo

    View Slide

  32. Inline Editing
    Docs: https://htmx.org/examples/click-to-edit/
    Demo: https://lunchdown.com/visits/

    View Slide

  33. Active Search
    Docs: https://htmx.org/examples/active-search/
    Demo: https://memecomplete.com/examples/

    View Slide

  34. Partial Update
    Docs: https://htmx.org/examples/click-to-load/
    Demo: https://memecomplete.com/custom/

    View Slide

  35. Infinite Scroll
    Docs: https://htmx.org/examples/infinite-scroll/
    Demo: https://mediavouch.com/feed/

    View Slide