hx-requests


Namehx-requests JSON
Version 0.35.3 PyPI version JSON
download
home_pagehttps://github.com/yaakovLowenstein/hx-requests
SummaryFacilitates the usage of HTMX with Django
upload_time2025-02-09 02:07:21
maintainerNone
docs_urlNone
authoryaakovLowenstein
requires_python<4.0,>=3.8
licenseMIT
keywords django htmx
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # hx-requests

Full documentation: [hx-requests Documentation](https://hx-requests.readthedocs.io/en/latest/#)

<br>

[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-blue.svg)](https://docs.astral.sh/ruff/formatter/)
[![Code style: djlint](https://img.shields.io/badge/html%20style-djlint-blue.svg)](https://www.djlint.com)

## Overview

### What Are hx-requests?

To start with a high-level explanation, `hx-requests` are quasi Django + Htmx views.
They mimic Django's class-based views but with added functionality to work seamlessly with Htmx. Using a View mixin, it elegantly handles multiple Htmx requests on a single page. Each Htmx request is routed to a specific hx-request (think of it as a view), which returns the necessary HTML to update the DOM. A more detailed explanation can be found [below](#why-use-hx-requests).

### Why The Name?

Excellent question! The package was named early on in the development process when the behavior wasn't exactly clear.
All that was clear was that there needed to be an easier way to work with Htmx in Django.
**Hx** comes from Htmx, and **requests** because every use of Htmx is a request to the server.
If it was named today, it would probably be called something like `Django-Htmx-Views`, but `hx-requests` has stuck.

### Why Use hx-requests?

This is where we will get into the details of why `hx-requests` is needed.

There are multiple ways of integrating Htmx in a Django project.

#### 1. Using The Page View

The most common way is re-hitting the view that loaded the page.

The base view:

```python
class MyView(View):
    def get(self, request):
        return render(request, "my_template.html")
```

The template:

```html
<div hx-get="{% url 'my_view' %}">
    <p>Click me to use hx-get</p>
</div>
```

Handling the request:

```python
class MyView(View):
    def get(self, request):
        if request.headers.get("HX-Request"):
            return render(request, "my_template.html")
        return render(request, "my_template.html")
```

This approach works well for views with one Htmx request, but what if you have multiple Htmx requests on the same page?

Handling multiple Htmx requests:

```python
class MyView(View):
    def get(self, request):
        if request.headers.get("HX-Request"):
            if request.headers.get("Unique-Identifier") == "get_user_info":
                return render(request, "user_info_card.html")
            if request.headers.get("Unique-Identifier") == "get_user_profile":
                return render(request, "user_profile_card.html")
        return render(request, "my_template.html")
```

**Issues with this approach:**

- It gets messy if there are multiple Htmx requests on the same page.
- Handling POST requests with specific logic dynamically adds complexity.
- The logic for handling Htmx requests is tightly coupled to the view, making reuse difficult.

#### 2. Using Separate Views

Each Htmx request is routed to a separate view.

```python
# Page View
class MyView(View):
    def get(self, request):
        context = {'complex-context': "This is a complex context"}
        return render(request, "my_template.html", context)

# Htmx Request 1
class GetUserInfo(View):
    def get(self, request):
        return render(request, "user_info_card.html")

# Htmx Request 2
class GetUserProfile(View):
    def get(self, request):
        return render(request, "user_profile_card.html")
```

**Issues with this approach:**

- Each Htmx request requires a separate URL.
- Context is not shared across views, leading to code duplication.
- Using Django's built-in `ListView`, duplicating logic for Htmx requests becomes a nightmare.

### hx-requests: The Solution

`hx-requests` solves all of these issues. It allows multiple Htmx requests on the same page while sharing context across requests. Every Htmx request routes to an [`hx-request`](#what-are-hx-requests).

**Advantages:**

- The parent view is not cluttered with extra logic for handling multiple Htmx requests.
- HxRequests are reusable across views, reducing duplication.
- No extra URLs are needed.
- The view's context is shared across all Htmx requests, making it easier to manage.

Additionally, `hx-requests` includes built-in functionality to help with common Htmx use cases:

- Form validation and automatic return of errors when using `FormHxRequest`.
- Easy integration with Django's messages framework.
- Compatibility with [`django-render-block`](https://github.com/clokep/django-render-block) for partial template rendering.
- Built-in support for handling modals with Htmx.

Full documentation: [hx-requests Documentation](https://hx-requests.readthedocs.io/en/latest/#)

---

# Contributing to this repository

## Getting setup

- This project is using poetry
- pre-commit is used for CI (code formatting, linting, etc...)
- There is a dev container that can be used with vs-code

## Committing

Must follow [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/yaakovLowenstein/hx-requests",
    "name": "hx-requests",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": null,
    "keywords": "django, htmx",
    "author": "yaakovLowenstein",
    "author_email": "lowensteinyaakov@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/e8/f2/da9042613f37a0a4e4c77dc52bde2d1397393e41bdceb3eb4e7fd0d63159/hx_requests-0.35.3.tar.gz",
    "platform": null,
    "description": "# hx-requests\n\nFull documentation: [hx-requests Documentation](https://hx-requests.readthedocs.io/en/latest/#)\n\n<br>\n\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)\n[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-blue.svg)](https://docs.astral.sh/ruff/formatter/)\n[![Code style: djlint](https://img.shields.io/badge/html%20style-djlint-blue.svg)](https://www.djlint.com)\n\n## Overview\n\n### What Are hx-requests?\n\nTo start with a high-level explanation, `hx-requests` are quasi Django + Htmx views.\nThey mimic Django's class-based views but with added functionality to work seamlessly with Htmx. Using a View mixin, it elegantly handles multiple Htmx requests on a single page. Each Htmx request is routed to a specific hx-request (think of it as a view), which returns the necessary HTML to update the DOM. A more detailed explanation can be found [below](#why-use-hx-requests).\n\n### Why The Name?\n\nExcellent question! The package was named early on in the development process when the behavior wasn't exactly clear.\nAll that was clear was that there needed to be an easier way to work with Htmx in Django.\n**Hx** comes from Htmx, and **requests** because every use of Htmx is a request to the server.\nIf it was named today, it would probably be called something like `Django-Htmx-Views`, but `hx-requests` has stuck.\n\n### Why Use hx-requests?\n\nThis is where we will get into the details of why `hx-requests` is needed.\n\nThere are multiple ways of integrating Htmx in a Django project.\n\n#### 1. Using The Page View\n\nThe most common way is re-hitting the view that loaded the page.\n\nThe base view:\n\n```python\nclass MyView(View):\n    def get(self, request):\n        return render(request, \"my_template.html\")\n```\n\nThe template:\n\n```html\n<div hx-get=\"{% url 'my_view' %}\">\n    <p>Click me to use hx-get</p>\n</div>\n```\n\nHandling the request:\n\n```python\nclass MyView(View):\n    def get(self, request):\n        if request.headers.get(\"HX-Request\"):\n            return render(request, \"my_template.html\")\n        return render(request, \"my_template.html\")\n```\n\nThis approach works well for views with one Htmx request, but what if you have multiple Htmx requests on the same page?\n\nHandling multiple Htmx requests:\n\n```python\nclass MyView(View):\n    def get(self, request):\n        if request.headers.get(\"HX-Request\"):\n            if request.headers.get(\"Unique-Identifier\") == \"get_user_info\":\n                return render(request, \"user_info_card.html\")\n            if request.headers.get(\"Unique-Identifier\") == \"get_user_profile\":\n                return render(request, \"user_profile_card.html\")\n        return render(request, \"my_template.html\")\n```\n\n**Issues with this approach:**\n\n- It gets messy if there are multiple Htmx requests on the same page.\n- Handling POST requests with specific logic dynamically adds complexity.\n- The logic for handling Htmx requests is tightly coupled to the view, making reuse difficult.\n\n#### 2. Using Separate Views\n\nEach Htmx request is routed to a separate view.\n\n```python\n# Page View\nclass MyView(View):\n    def get(self, request):\n        context = {'complex-context': \"This is a complex context\"}\n        return render(request, \"my_template.html\", context)\n\n# Htmx Request 1\nclass GetUserInfo(View):\n    def get(self, request):\n        return render(request, \"user_info_card.html\")\n\n# Htmx Request 2\nclass GetUserProfile(View):\n    def get(self, request):\n        return render(request, \"user_profile_card.html\")\n```\n\n**Issues with this approach:**\n\n- Each Htmx request requires a separate URL.\n- Context is not shared across views, leading to code duplication.\n- Using Django's built-in `ListView`, duplicating logic for Htmx requests becomes a nightmare.\n\n### hx-requests: The Solution\n\n`hx-requests` solves all of these issues. It allows multiple Htmx requests on the same page while sharing context across requests. Every Htmx request routes to an [`hx-request`](#what-are-hx-requests).\n\n**Advantages:**\n\n- The parent view is not cluttered with extra logic for handling multiple Htmx requests.\n- HxRequests are reusable across views, reducing duplication.\n- No extra URLs are needed.\n- The view's context is shared across all Htmx requests, making it easier to manage.\n\nAdditionally, `hx-requests` includes built-in functionality to help with common Htmx use cases:\n\n- Form validation and automatic return of errors when using `FormHxRequest`.\n- Easy integration with Django's messages framework.\n- Compatibility with [`django-render-block`](https://github.com/clokep/django-render-block) for partial template rendering.\n- Built-in support for handling modals with Htmx.\n\nFull documentation: [hx-requests Documentation](https://hx-requests.readthedocs.io/en/latest/#)\n\n---\n\n# Contributing to this repository\n\n## Getting setup\n\n- This project is using poetry\n- pre-commit is used for CI (code formatting, linting, etc...)\n- There is a dev container that can be used with vs-code\n\n## Committing\n\nMust follow [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/).\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Facilitates the usage of HTMX with Django",
    "version": "0.35.3",
    "project_urls": {
        "Homepage": "https://github.com/yaakovLowenstein/hx-requests",
        "Repository": "https://github.com/yaakovLowenstein/hx-requests"
    },
    "split_keywords": [
        "django",
        " htmx"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f8ac99feb2a6de78c802e1037e5e126e74ffdac2e9eb2dfd4b05e36bfdf76c32",
                "md5": "ee055573467b4a06b957466989223136",
                "sha256": "1120286a6655b720acc2b107ae4b13ea64d7b00d6d908a53fba1fac7798bb709"
            },
            "downloads": -1,
            "filename": "hx_requests-0.35.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ee055573467b4a06b957466989223136",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 16541,
            "upload_time": "2025-02-09T02:07:19",
            "upload_time_iso_8601": "2025-02-09T02:07:19.224882Z",
            "url": "https://files.pythonhosted.org/packages/f8/ac/99feb2a6de78c802e1037e5e126e74ffdac2e9eb2dfd4b05e36bfdf76c32/hx_requests-0.35.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e8f2da9042613f37a0a4e4c77dc52bde2d1397393e41bdceb3eb4e7fd0d63159",
                "md5": "ce1994444c771bfd0d982b4e9af082bb",
                "sha256": "349a642f7d7b80969894dfb6c409e6b8246471559ac437c78f15be6be208d0f4"
            },
            "downloads": -1,
            "filename": "hx_requests-0.35.3.tar.gz",
            "has_sig": false,
            "md5_digest": "ce1994444c771bfd0d982b4e9af082bb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 15822,
            "upload_time": "2025-02-09T02:07:21",
            "upload_time_iso_8601": "2025-02-09T02:07:21.106065Z",
            "url": "https://files.pythonhosted.org/packages/e8/f2/da9042613f37a0a4e4c77dc52bde2d1397393e41bdceb3eb4e7fd0d63159/hx_requests-0.35.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-09 02:07:21",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "yaakovLowenstein",
    "github_project": "hx-requests",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "hx-requests"
}
        
Elapsed time: 5.70865s