# Simplifying Dynamic Web Development with Django and HTMX (Part 4): How to Handle Payloads? When sending POST requests using `fetch` for Ajax in traditional JavaScript, you typically assemble the payload directly using `JSON.stringify()`. It generally looks like this: ```JavaScript fetch("/api/todos/", { method: "POST", headers: { "Content-Type": "application/json", "X-CSRFToken": csrftoken }, body: JSON.stringify({ title: "장보기", done: false, priority: 3 }) }) ``` But what about **HTMX**? How exactly does `hx-post` send data to the server? Many examples only demonstrate very simple functionalities, making it surprisingly difficult to find practical examples for constructing and sending complex payloads. In this post, we'll thoroughly explore HTMX's data transmission methods and how to handle them on the server-side. ![Diagram illustrating data flow in HTMX with Django](/media/whitedec/blog_img/fbe9c41ba8ea4eabb78e760e1f768482.webp) ------ ## HTMX Data Transmission Methods {#sec-1f930b1a0dad} The approach to payloads with `fetch` and data transmission with `hx-post` are quite distinct. With `fetch`, developers directly create objects and convert them to JSON for the request body. In contrast, **HTMX primarily collects values from the DOM for transmission**. HTMX's philosophy isn't about "directly assembling JS objects," but rather **"gathering values from HTML elements to construct request parameters."** It typically uses the following three methods for this purpose. ### 1) Sending Values Based on Forms {#sec-f5086851ac19} This is the most HTML-native approach and integrates well with Django. ```html
``` In this scenario, HTMX collects the input values within the form and sends them with the request. The default encoding is **URL-encoded form data**, just like a standard form submission. In a Django view, you can receive them as usual: ```Python def create_todo(request): title = request.POST.get("title") priority = request.POST.get("priority") done = request.POST.get("done") ``` ### 2) Including Values from Other Elements Without a Form: `hx-include` {#sec-a2c0e1f9e1ca} This is used when you want to attach `hx-post` to a single button and selectively send input values located elsewhere. ```HTML ``` `hx-include` includes the values of the specified elements in the request. This allows you to achieve a payload-like result without wrapping everything in a `
`, which is very useful when there are fewer input fields. ### 3) Adding Hidden or Computed Values: `hx-vals` {#sec-f3e44212771a} This feature is the closest to the concept of directly constructing part of the payload object in `fetch`. ```HTML ``` `hx-vals` adds additional parameters to the request. While it defaults to JSON-like syntax as shown above, you can also send dynamic JavaScript computed values by prefixing with `js:`. ```HTML ``` In this case, Django still reads these values from `request.POST`. This is because `hx-vals` is about **"defining values using JSON-like syntax,"** not about making the request body itself JSON. ------ ## Important Note: `hx-vals` Is Not the Same as "JSON Payload" {#sec-c31077e0c2ea} This is often the most confusing aspect when first encountering HTMX. ```HTML ``` Now, this becomes the familiar JSON payload method. In this case, the Django view will find `request.POST` empty, so you'll need to read `request.body` directly. ```Python import json def create_todo_api(request): data = json.loads(request.body) title = data.get("title") # ... 로직 처리 ... return JsonResponse({"ok": True}) ``` ------ ## HTMX and DRF Have Philosophical Gaps, But Don't Necessarily Need to Merge {#sec-aff378931c81} While you can send JSON using an extension, the question remains whether this aligns with the HTMX philosophy. This is where the two philosophies of **"data-centric (DRF)"** and **"hypermedia-centric (HTMX)"** diverge. If you've decided to properly leverage HTMX, I believe it's worth stepping away from a data-centric mindset for a moment. Sending values via ``, `hx-include`, and `hx-vals`, and having the server receive them via `request.POST` to **return HTML snippets instead of JSON**—that's where HTMX truly shines. ### But What If You Don't Want to Give Up DRF Serializers? {#sec-2a26aeec3b61} DRF's serializers are incredibly powerful. Should you abandon this convenient validation tool and resort to tedious `request.POST.get()` calls just because you're using HTMX? Fortunately, DRF serializers are excellent at validating not only JSON but also form data. Since this topic could get lengthy, we'll delve into **"The Coexistence of HTMX and DRF Serializers"** in the next part. ------ ## Conclusion {#sec-ab81cf195815} To summarize today's content: 1. **HTMX primarily collects values from the DOM.** Its approach differs from `fetch`, where you manually construct payload objects. 2. **Three transmission methods:** `` for sending everything, `hx-include` for selecting specific values, and `hx-vals` for adding custom values. 3. **The default is form data.** Be aware that `hx-vals` uses JSON syntax, but it doesn't send an actual JSON body. 4. **If JSON is essential, use the `json-enc` extension.** However, remember that HTMX's true strength lies in exchanging HTML fragments. In the next session, we'll return with methods to integrate the convenience of DRF into HTMX! **Related Posts** - [Simplifying Dynamic Web Development with Django and HTMX (Part 1)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification/) - [Simplifying Dynamic Web Development with Django and HTMX - Ajax (Part 2)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-2/) - [Simplifying Dynamic Web Development with Django and HTMX (Part 3): Django Integration Methods](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-3/) - [Simplifying Dynamic Web Development with Django and HTMX (Part 5)](/ko/whitedec/2025/1/27/django-htmx-advanced-features/) - [Simplifying Dynamic Web Development with Django and HTMX (Part 6): HTML Response Methods](/ko/whitedec/2025/1/27/django-htmx-html-response/) - [Simplifying Dynamic Web Development with Django and HTMX (Part 7): JSON Response Methods](/ko/whitedec/2025/1/27/django-htmx-json-response/)