Build a Simple CRM With Django and HTMX— Frontend Development | by John Galiszewski | Jul, 2022

Creating the app templates


In this article, we’ll continue where we left off: by creating the templates for our client_relationship_manager app. I recommend reading part one, if you haven’t already, where I show you how to develop the backend for this project.

My goal for this series is to teach you how to create a dynamic CRUD application to keep track of clients and their contact information using Django and HTMX.

I’ll start by showing you how to organize the templates. The HtmxResponseMiddleware requires us to set them up uniquely.

1*lVs2H9HJkVpi Nkr44UzDg

Any page templates inside an application subdirectory will extend from base.html. Or partial.html if it’s an HTMX response.


The base.html template includes standard elements like the title, meta tags, CSS, and JavaScript. We also pass a csrf_token to the header with the hx-headers attribute.

It’s most convenient to place hx-headers on your <body> tag, as then all elements will inherit it. (Source: htmx docs.)

Next is a very simple navbar, a container for messages, a container for breadcrumbs, and a container for the htmxCanvas. Notice in the navbar we use both the app namespace and URL pattern name to reverse the URL rather than hardcoding it.


Above is the base template used for HTMX responses. It updates the page title, breadcrumbs, and any messages returned from the request using the hx-swap-oob attribute. The content inside the canvas block tag gets swapped into the htmxCanvas.


All of the app templates will follow a similar layout to this one. First, extend base_template, passed into the response from HtmxResponseMiddleware. Then we’ll provide the page title, breadcrumbs, and canvas content.

In the first row of the canvas content, we put the page heading, an htmx active search bar, and a button to add new clients. The rest of the page is a for loop to display a list of clients in a table.

In the search bar, we’ll send our request to the search URL in the CRM app, send the response to htmxCanvas, and push the URL to the browser history. Also, add the hx-preserve attribute, it’ll prevent the search bar from reloading when the search results render.

The hx-preserve attribute allows you to keep an element unchanged during HTML replacement. (Source: htmx docs.)

At this point, you can go into the default admin to add a few test clients and look at the home page. It should look like the image below:



The search results template is similar to the index template. The only difference is the title, breadcrumbs, and instead of a button to add clients, we show the number of results for the query.

The image below is what the page will look like:


Again, on the detail page, we extend base_template, add a title, and some breadcrumbs, then we get to the canvas content.

There are two buttons to update or delete the client. Then we display all of the client’s contact information.

1*ZuSg6JCjDmj EBrPglgFdQ


Here we will use the forms we created in Notice it was simpler to add attributes to the form fields there, so now we can use the {{ form }} template tag.

1*o bu7oQUHMrpCArBW1N8Ww

Submitting the form will direct you to the new client’s detail page, where you’ll see the messages we added to the partial.html file. Reload the page, use the close button, or navigate to a new page, and the message will disappear as expected.


The update page is similar to the create page. One key difference is the client instance displayed in the form fields.


As we get closer to the end, notice how the application templates follow the same basic layout, accepted by both base templates (base.html and partial.html). This framework makes it easier to add more complex operations down the line.


The DeleteClientView gives us a confirmation page where we can confirm whether we want to delete or cancel. You can use the hx-confirm attribute from HTMX on the client detail page instead if you prefer an alert over a dedicated delete page!

News Credit

%d bloggers like this: