MacMusic  |  PcMusic  |  440 Software  |  440 Forums  |  440TV  |  Zicos
django
Search

Dynamic web apps with HTMX, Python, and Django

Wednesday February 12, 2025. 10:00 AM , from InfoWorld
Dynamic web apps with HTMX, Python, and Django
Python is one of the most popular programming language today, in part due to its large ecosystem of tools for data science and AI applications. But Python is also a popular choice for developing web apps, particularly using the Django web framework. I’ve written a few articles demonstrating how HTMX integrates with different technologies and stacks, including Java (via Spring Boot) and JavaScript (via Bun, a JavaScript runtime). Now let’s take Python, Django, and HTMX out for a spin.

Django is a mature framework that can be combined with HTMX to develop fully interactive web applications without directly coding in JavaScript. To start, you’ll need to install Python 3, then install the Django framework. Once you have those set up in your development environment, you can create a directory and start a new project using the django-admin command:

$ mkdir quoteproject
$ django-admin startproject quoteproject quoteproject/
$ cd quoteproject

It’s also a good practice to set up an alias so $ python refers to the python3 runtime:

$ alias python=python3

If you need to access the development server from outside of localhost, you can modify the allowed host settings at quoteproject/settings.py:

ALLOWED_HOSTS = ['*']

Note that this allows all incoming requests, so it’s not very secure. You can fine-tune the setting to accept only your client IP. Either way, we can now run the development server:

$ python manage.py runserver 3000

If you want to listen for external hosts, use: $ python manage.py runserver 0.0.0.0:3000.

If you check the host server, you should see a welcome screen like the one here:

The components

We’ll build an application that lets us list and create quotes. I’ve used this example in previous articles, as it’s useful for demonstrating server-side application capabilities. It consists of three primary components, which we’ll build with Django and a dash of HTMX:

Models

Views

Routes

As a model-view-template (MVT) framework, Django is slightly different from MVC (model-view-controller) frameworks like Express and Spring. But the distinction isn’t hugely important. A Django application’s main jobs of routing requests, preparing a model, and rendering the responses are all handled by well-defined components.

Django also ships with built-in persistence, which makes saving data and managing a schema in an SQL database very simple. Our application includes an SQLite database instance, which we‘ll use for development.

Now let’s look at the main components.

Developing the model in Django

We only need a single model for this example, which will handle quotes:

// quoteapp/models.py
from django.db import models

class Quote(models.Model):
text = models.TextField()
author = models.CharField(max_length=255)
from django.db import models

This is Django’s ORM syntax for a persistent object called Quote. It contains two fields: a large TextField called text and a 255-length CharField called author. This gives us a lot of power, including the ability to list and perform CRUD operations on Quote objects.

Whenever we make changes to the database, we can use Django’s tooling to update the schema:

$ python manage.py makemigrations
$ python manage.py migrate

The makemigrations command creates a new migration file if any schema changes are detected. (These are found in quoteapp/migrations, but you won’t typically need to interact with them directly.) The migrate command applies the changes.

Conflicts with schema changes
When several people make migration changes and then check them into version control, Django has mechanisms for addressing any version conflicts that may arise. See Django’s migrations documentation to learn more.

Constructing the view

Next up, let’s consider the view, which accepts a request and prepares the model (if necessary), and hands it off to be rendered as a response. We’ll only need one view, found at quoteapp/views.py:

// cat quoteapp/views.py
from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import HttpResponse
from.models import Quote

def index(request):
if request.method == 'POST':
text = request.POST.get('text')
author = request.POST.get('author')
if text and author:
new_quote = Quote.objects.create(text=text, author=author)
# Render the new quote HTML
html = render_to_string('quoteapp/quote_item.html', {'quote': new_quote})
return HttpResponse(html)
quotes = Quote.objects.all()
return render(request, 'quoteapp/index.html', {'quotes': quotes})

In this view, we import the Quote model and use it to craft a response in the index function. The request argument gives us access to all the information we need coming from the client. If the method is POST, we assemble a new Quote object and use Quote.objects.create() to insert it into the database. As a response, we send back just the markup for the new quote, because HTMX will insert it into the list on the front end.

If the method is a GET, we can use Quote.objects.all() to recover the existing set of quotes and send the markup for the whole page at quoteapp/index.html.

Django templates with HTMX

Quote_item.html and index.html are both templates. They let us take the model provided by the view and construct markup. These reside in a special template path. Here’s the simple quote item template, which renders an item:

// quoteapp/templates/quoteapp/quote_item.html
{{ quote.text }} - {{ quote.author }}

And here’s the main index template:

// quoteapp/templates/quoteapp/index.html
Quotes

{% for quote in quotes %}
{{ quote.text }} - {{ quote.author }}
{% endfor %}

{% csrf_token %}


Add Quote

/python-django-htmx/quoteproject$ cat quoteapp/urls.py
from django.urls import path
from. import views

urlpatterns = [
path('', views.index, name='index'),
]

These templates use the Django template language, which works similarly to Pug or Thymeleaf. Django’s template language lets us use HTML with access to the exposed Quote model. We use the {{ }} and {% %} variables and tags to access variables in Python. For example, we could use {% for quote in quotes %} to set up a loop that iterates over the quotes, exposing a quote variable on each iteration.

Because HTMX is simply an extension of HTML, we can use its properties in the Django template just like any other HTML:

hx-post indicates this form should be POSTed, and where to send the data.  In this case, we’re posting to the index endpoint in views.py.

hx-target indicates where to put the response from the server.  In this case, we want to append it to the list, because the server will send the new quote item.

hx-swap lets us fine-tune exactly how the response is handled.  In this case, we stick it beforeend, meaning we want it to be the final element in the list.

Routing requests

Now we need to tell Django what requests go where. Django uses a project and app concept, where a single project can contain many apps. The basic routing occurs in the project, which was generated by the project creator. Now we’ll add a new route for our application:

// quoteproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('quoteapp.urls'))
]

The one we’re interested in is routing the root path (‘’) to the included quoteapp.urls, which we define here:

// quoteapp/urls.py
from django.urls import path
from. import views

urlpatterns = [
path('', views.index, name='index'),
]

This also tells us where the empty ‘’ path should go, which is to call the index function we saw earlier in views.py. The name argument provides a handle to the path that we can use in links in the project. There’s more information about the path function and URL handling in the Django docs.

Run the app

We’re almost ready to run and test the application. A final step is to tell Django the quoteapp is part of the quoteproject, which we do in settings.py:

// quoteproject/settings.py

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'quoteapp'
]

In this case, we’ve added the quoteapp directory to the INSTALLED_APPS array.

Now if we run the app with $ python manage.py runserver 3000, we’ll see a simple but functional UI:

Conclusion

This article demonstrated the basic elements of building a web application using Python, Django, and HTMX. Without much more work, we could use the same routing and endpoint logic to build APIs (consider Django REST). Django is a well-designed and mature framework for Python; it works smoothly and rarely gets in your way. Django is geared toward SQL databases, so it may not be the best choice if you prefer to use a NoSQL database like MongoDB. On the other hand, it makes using SQL data stores very convenient.

If you’re a Python developer, Django is a clear winner for building SQL-based, data-driven web applications. For more straightforward RESTful APIs, you might want something more focused like Falcon or Flask.

Not surprisingly, the experience of using Python, Django, and HTMX together is comparable to using HTMX with Java and Spring Boot or JavaScript and Express, or C# and.Net. Regardless of the framework or stack you choose, it seems that HTMX serves its purpose well, in making everyday HTML UIs more powerful with a minimum of additional coding.
https://www.infoworld.com/article/3802689/dynamic-web-apps-with-htmx-python-and-django.html

Related News

News copyright owned by their original publishers | Copyright © 2004 - 2025 Zicos / 440Network
Current Date
Feb, Thu 13 - 11:39 CET