{"id":13780677,"url":"https://github.com/nikalexis/django_htmx_ui","last_synced_at":"2025-05-11T14:32:59.087Z","repository":{"id":90064493,"uuid":"599012897","full_name":"nikalexis/django_htmx_ui","owner":"nikalexis","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-27T20:10:44.000Z","size":165,"stargazers_count":16,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-16T02:49:03.385Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nikalexis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-02-08T09:15:24.000Z","updated_at":"2024-10-24T09:13:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"cffc0cef-f01a-48a1-8e8d-7077f91a0d67","html_url":"https://github.com/nikalexis/django_htmx_ui","commit_stats":{"total_commits":14,"total_committers":1,"mean_commits":14.0,"dds":0.0,"last_synced_commit":"07c05b0667c263c9b0d0cc019781ee903a423706"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikalexis%2Fdjango_htmx_ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikalexis%2Fdjango_htmx_ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikalexis%2Fdjango_htmx_ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikalexis%2Fdjango_htmx_ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikalexis","download_url":"https://codeload.github.com/nikalexis/django_htmx_ui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253580117,"owners_count":21930885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:01:18.597Z","updated_at":"2025-05-11T14:32:58.772Z","avatar_url":"https://github.com/nikalexis.png","language":"Python","funding_links":[],"categories":["Third Party Packages 📦 \u003ca name = \"tools\"\u003e\u003c/a\u003e"],"sub_categories":["Frameworks"],"readme":"# Intro\n\n## What is `django_htmx_ui` library\n\nThis library is made to combine and help leveraging:\n* the full-stack [django](https://www.djangoproject.com/) framework\n* the frontend [htmx](https://htmx.org/) framework\n* the [django-htmx](https://django-htmx.readthedocs.io/en/latest/) library\n* the [jinja](https://jinja.palletsprojects.com/en/3.1.x/) template engine\n\nIt is basically a django app that provides:\n* Extended django `Views` with htmx build-in functionality\n* `CRUD Views` (Create, Retrieve, Update, Delete) for django models\n* Some extra `Mixins` to use with your `Views` to make life easier\n* A ready to use `jinja` environment\n* Some `Middlewares` for automations\n* Extra `utils` and `decorators` for common use cases\n\n# Requirements\n\n* Python 3.11\n* Django 4.1\n* htmx 1.8\n* jinja 3.1\n\n# Installation\n\n  * via pip\n\n        pip install django_htmx_ui`\n\n  * or add library into requirements.txt\n\n        django_htmx_ui\n\n# Usage\n\n## Setup\n\n1. Add the app in your `settings.py`:\n\n        INSTALLED_APPS = [\n            # ...\n            'django_htmx_ui',\n            # ...\n        ]\n\n2. Add the middlewares you would like to use in your `settings.py`:\n\n        MIDDLEWARE = [\n             # ...\n            'django_htmx_ui.middleware.HtmxMessagesMiddleware',\n             # ...\n        ]\n\n3. Add the jinja environment in your `settings.py`:\n\n        TEMPLATES = [\n             {\n                 'BACKEND': 'django.template.backends.jinja2.Jinja2',\n                 'DIRS': [BASE_DIR / 'jinja2'],\n                 'APP_DIRS': True,\n                 'OPTIONS': {\n                     'environment': 'django_htmx_ui.jinja.environment',\n                 },\n             },\n             # ... you can also keep your django templates engine here ...\n        ]\n      \n    You can also extend it by creating your own in `your_project/jinja.py` module:\n\n        import django_htmx_ui.jinja\n\n        def environment(**options):\n            env = django_htmx_ui.jinja.environment(**options)\n\n            # Add your own jinja functionalities like globals or filters here.\n          \n            return env\n\n    ...and then replace the `'environment'` variable inside the `'OPTIONS'` key:\n\n        # ...\n        'OPTIONS': {\n            'environment': 'your_project.jinja.environment',\n        },\n        # ...\n    \n    Finally, to use the jinja FORM_RENDERER, add / replace in your `settings.py`:\n\n        from django_htmx_ui.jinja import get_form_renderer\n        # ...\n        FORM_RENDERER = get_form_renderer()\n\n## Views\n\n### Defining views\n\nThe recommended structure to place your views inside your project is the following:\n\n* `django_project/`\n  * `django_app/`\n    * `views/`\n      * `module_a.py`\n      * `module_b.py`\n\nInside each view module (e.g. `module_a.py`) you can assign some optional module globals,\nthat will be used by all your `ViewTemplate` classes inside the module, such as:\n\n`SLUG`: A slug name for the module  \n`TEMPLATES_DIR`: The directory of the view's templates    \n`TITLE`: A title for all views  \n`ICON`: An icon for all views  \n`MODEL`: A model in your database to automate the CRUD functionality for this module  \n\nThen you can create some `TemplateView` classes, like this:\n\n`module_a` file:\n\n    class UserDashboard(PrivateTemplateView):\n        ... your special properties go here ...\n\n`module_b` file:\n\n    MODEL = User\n\n    class List(CrudListMixin, PrivateTemplateView):\n        ... your special properties go here ...\n\n    class Update(CrudUpdateMixin, PrivateTemplateView):\n        ... your special properties go here ...\n\n    class Display(CrudDisplayMixin, PrivateTemplateView):\n        ... your special properties go here ...\n\nBy default, the templates will be searched automatically in the directories:\n\n* `django_project/`\n  * `django_app/`\n    * `jinja2/`\n      * `django_app/`\n        * `module_a/`\n          * `user_dashboard.html` for class named `UserDashboard` in your `module_a`\n        * `module_b/`\n          * `list.html` for class named `List` in your `module_b`\n          * `update.html` for class named `Update` in your `module_b`\n          * `display.html` for class named `Display` in your `module_b`\n\nTo make you life even easier you can use the `django_htmx_ui.utils.collect_paths`\nfunction to help you automatically build your app's `urls.py` file.\n\nFor example `django_project/django_app/urls.py` should be:\n\n    from django_app.views import module_a, module_b\n    from django_htmx_ui.utils import collect_paths\n    \n    \n    app_name = 'django_app'\n    urlpatterns = [\n        collect_paths(module_a, app_name),\n        collect_paths(module_b, app_name),\n    ]\n\n### Best practices when developing your project\n\n#### Creating origin root templates containing the \u003chtml\u003e tag pages.\n\nWhen the browser makes the first http, this will be outside htmx.\nFrom now on, we will call this page an origin page, because it must serve all the basic\ncomponents to load a standard html page, like \u003chtml\u003e, \u003chead\u003e tag and javascript\nlibraries including htmx.\n\nIf you build a big project, chances are that you will need more than one origin pages.\n\nFor example, login, signup, password forget, errors etc. pages, can be part of an origin\npage called `WelcomeOrigin(OriginTemplateMixin, PublicTemplateView)`.\nPlease notive that we used the `OriginTemplateMixin` to tag that this view is an origin\nand the `PublicTemplateView` to tag that it will be accessible by everyone.\n\nOther pages, like dashboard, account, user profile, etc. need to be accessible only by\nthe signed-in user, so the origin page could be called\n`DefaultPanelOrigin(OriginTemplateMixin, PrivateTemplateView)`.\n\n`WelcomeOrigin` and `DefaultPanelOrigin` templates will be used as the base html page.\n\n#### Creating your sub-pages\n\nAll sub-pages can extend these two basic classes like this:\n`Login(WelcomeOrigin)` or `Dashboard(DefaultPanelOrigin)`.\nThese sub-pages will have their own templates, but will be served by a htmx lazy-load get.\n\n#### Creating a partial sub-page\n\nIf you now want to create a Widget inside your user's dashboard page, you can define\nits view as `Widget(PartialTemplateMixin, DefaultPanelOrigin)`. Please, notice the usage of the\n`PartialTemplateMixin`. When you add this Mixin, it means that this view can only be requested\nvia a htmx request, therefore it can't be opened directly from the browser's address\nbar.\n\n#### Creating your first html with htmx usage\n\nThis is a very simplified example to make you understand what this library does.\n\nFirstlt, we must create some views:\n\n`app_name/views/welcome.py`:\n\n    class WelcomeOrigin(OriginTemplateMixin, PublicTemplateView):\n        pass\n\n    class Login(FormMixin, WelcomeOrigin):\n        \n        class Form(forms.Form):\n            user = forms.CharField()\n            password = forms.CharField()\n\nIn order to display the above views, we create also their templates:\n\n`app_name/jinja2/app_name/welcome/welcome_origin.html`:\n\n    \u003chtml\u003e\n        \u003chead\u003e...\u003c/head\u003e\n        \u003cbody\u003e\n            \u003cdiv hx-get=\"{{ url }}\"\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n\n`app_name/jinja2/app_name/welcome/login.html`:\n    \n    \u003cp\u003eLogin Form:\u003c/p\u003e\n    \u003cform\u003e\n        {{ form }}\n    \u003c/form\u003e\n\nThis an incomplete and simplified example to demonstrate how this library works.\nYou can create more complex scenarios, if you dive in the following documentation.\n\n### Generic Views\n\nThe following `Views` are basically an extended version of django's class `TemplateView`\nto include all the helper properties and the shortcuts to make your life easier\nwith the combination of the htmx library. The first step is to choose the right\nclass type to extend, according to your needs, and apply all the extra properties.\nFeel free to override any properties and extend futher more your own classes. \n\n#### *django_htmx_ui.views.generic.*__PublicTemplateView__\n\nThis class extends the django's `TemplateView` class and\nis the main class that provides the basic functionality.\nThe `Public` keyword in the name refers that the class is\n__not__ requiring the user to be authenticated in order to\naccess the view.\n\n_Provides the following attributes:_\n\n`on_get (self, request, *args, **kwargs)` method\n\nThis is called any time a http __GET__ request is made to the view.\nYou can return a django's `Response` object.\nIf you don't return, the template of the view will be\nrendered and returned as a response.\n\n`on_post (self, request, *args, **kwargs)` method\n\nThis is called any time a http __POST__ request is made to the view.\nYou can return a django's `Response` object.\nIf you don't return, the template of the view will be\nrendered and returned as a response.\n\n`request` property\n\nThis property refers to the `Request` django's object.\nYou can use this property in any method you describe in your views.\n\n`response` property\n\nAnother way you can set a response, is by setting the `self.response` property.\nThis is a rare case and in most cases you will not need to set or access this\nproperty directly.\n\n`response_location (self, *args, **kwargs)` method\n\nWhen the view is used by a htmx request, you can use this function to make a\n`django_htmx.http.HttpResponseLocation` response. All `args` and `kwargs` are\npassed through.\n\n`response_no_content (self)` method\n\nUse this as a response when you have no content to send.\n\n`redirect (self, url)` method\n\nUse this as a response to redirect the browser's location in another path.\nKeep in mind that the whole will be refreshed, even if you are inside a htmx request.\n\n`url` context property\n\nUse this property to retrieve current view's `UrlView` object.\nYou can use inside your template file via the variable `{{ url }}`.\nYou can also add GET query parameters easily with `{{ url.query(page=1) }}`.\nSee the `UrlView` object description for more.\n\n`url(view, *args, **kwargs)` method\n\nThe `url` attribute can also be called as a method.\nUse this method to build a new `UrlView` object, based on a `TemplateView` object.\nThe `view` parameter can be either a view name (e.g. `'django_app:module:my_view'`) or\na python view path (e.g. `'django_app.views.module.MyView'`) or\na `TemplateView` object.\nAll `args` and `kwargs` are passed through to the django `reverse` function to build\nthe url.\nYou can use inside your template file with `{{ url('django_app:module:my_view') }}`.\n\n`location_bar` property\n\nThis property refers to the location (URL) bar of the browser.\nUnder the hook, it reads the htmx's `HX-Current-URL` header, and if this is not\navailable (aka is not a htmx request), it will read the `request.META['PATH_INFO']`.\nYou can also update the location bar anywhere in your view.\nSee the `Location` object description for more.\n\n`location_req` property\n\nThis property refers to the location (URL) of the current server request.\nUnder the hook, it will always read the `request.META['PATH_INFO']` and create a\n`Location` object for you.\nSee the `Location` object description for more.\n\n`headers` dictionary\n\nUse this dictionary property to add headers at the response.\n\n`trigger_client_event (self, *args, **kwargs)` method\n\nWhen the view is used by a htmx request, you can send a htmx client event using this\nfunction. All `args` and `kwargs` are passed through to the\n`django_htmx.http.trigger_client_event` function and finally to the browser event object.\n\n`slug_global` class property\n\nThis class property defines a global slug to use as a unique identifier for the `TemplateView`\nin you entire project.\nBy default, it's a combination of `slug_module` + `slug` described below.\n\n`slug_module` class property\n\nThis class property defines the slug name of the module that your view belongs to.\nYou can alter this property and build your own method if needed.\n\n`slug` class property\n\nThis class property defines the slug name of your view.\nBy default, it returns the name of the class with snake case conversion\n(e.g. MyClass becomes my_class).\nThis will be used with the module slug to build the view path ('my_module/my_class/').\nYou can alter this property and build your own method if needed.\n\n`path_route` class property\n\nThis class property defines the path route that your view wants to define in django's\nurl system.\nThis property is a shortcut for the parameter route of django's `re_path`,\nusing regular expressions to describe the route and the url parameters. \nSee also the `path` property following, if you need greater path handling.\n\n`path` class property\n\nThis class property returns the actual path object that django can recognize.\nYou can overwrite the property and return any of `path` or `re_path`.\n\nBe aware, that you must include the path of the view in your urls.\nAn easy way to do this, is by using the `collect_paths` helper method in the `utils.py`.\n\n`templates_dir` property\n\nThis property defines the directory that contains the templates files.\nThe default directory for every view module is the `app_name/module_name/` directory.\nYou can also change the module-wide default directory by setting a property called\n`TEMPLATES_DIR` inside the module.\n\n`template_file` property\n\nYou can set the template file of the view.\nBy default, the path is taken by the name of the view in a snake case plus a `.html`\nextension (e.g. `MyView` template file becomes `my_view.html`).\n\n`template_name` property\n\nThis is the full path of the template.\nIt is recommended as a first option to alter the templates_dir or templates_file\nproperties, by fill free to provide the final full path if needed.\nBy default, this property equals to `templates_dir` + `template_file`.\n\n`project_title` context property\n\nThis is the title of your project. It's part of the context for every view, so you can\nuse it inside your templates as a variable.\nBy default, the project title is the name of the directory that contains the\n`settings.py` file.\n\n`title` context property\n\nThis is the title of the view.\nYou can set this property and read it inside your templates.\nBy default, this property is derived by the module variable called `TITLE`.\nIf `TITLE` is not available, the project title is the default fallback.\n\n`icon` context property\n\nIt is sometimes useful in the frontend to print an icon, relative to the module the\nuser is viewing.\nYou can set this property and read it inside your templates.\nBy default, this property is derived by the module variable called `ICON`.\nIf `ICON` is not available, the empty string `''` is the default fallback.\n\n`message_info (self, message)` method  \n`message_success(self, message)` method  \n`message_warning(self, message)` method  \n`message_error(self, message)` method  \n\nYou can use these shortcut methods to send messages in the django's messaging system.\nEnable also the `HtmxMessagesMiddleware` to automatically send a htmx event every time\nnew messages are available to display in the frontend.\n\n\n#### *django_htmx_ui.views.generic.*__PrivateTemplateView__\n\nThis class extends the `PublicTemplateView` class and uses\nthe django's `LoginRequiredMixin` to check if the current user\nis authenticated. If not, makes a redirect to the login page.\n\n_Provides the following attributes:_\n\n`user` context property\n\nThis is a shortcut to the `request.user`.\nYou can use this inside your templates with `{{ user }}` to refer to the user object\nas needed.\n\n### Decorators\n\nUsing the following decorators you can tag any method inside your `TemplateView`\nand benefit from the automations it applies.\n\n#### *django_htmx_ui.utils.*__ContextProperty__\n\nIf you decorate any method with this magic decorator it will automatically convert it\nin a property and pass it through the template engine context as a variable.\n\nFor example:\n\n    class MyView(PublicTemplateView):\n\n        @ContextProperty\n        def variable_name(self):\n            return 'This is a test string to demonstrate the functionality.'\n\nNow you can use `{{ variable_name }}` inside your template file `my_view.html`.\n\n#### *django_htmx_ui.utils.*__ContextCachedProperty__\n\nThe same as `django_htmx_ui.utils.ContextProperty`, but the result is cached using the\n`functools.cached_property`. You can call many times the property\n(e.g. print a variable in many places inside a template), but the method will be called\nonly once.\n\n### CRUD Views\n\n#### *django_htmx_ui.views.crud.*__CrudMixin__\n\nThis is the Base Mixin for all following Crud* classes.\n\n_Provides the following attributes:_\n\n`permission` property\n\nYou can define this property to check if the current request or user has the permission\nto access the view and return True or False based on your own criteria.\nBy default, this property will return True and grant access to the view.\n\n#### *django_htmx_ui.views.crud.*__CrudCreateMixin__ (CrudMixin, FormMixin)\n\nAdd this Mixin to your `TemplateView` classes to add the object creation functionality.\nIt basically combines the `CrudMixin` and the `FormMixin` mixnins.\n\n#### *django_htmx_ui.views.crud.*__CrudRetrieveMixin__ (CrudMixin, FormMixin)\n#### *django_htmx_ui.views.crud.*__CrudListMixin__ (CrudMixin, FormMixin)\n\n`CrudListMixin` is an alias of `CrudRetrieveMixin`.\nAdd this Mixin to your `TemplateView` classes to add the object listing functionality.\nIt basically combines the `CrudMixin` mixnin, with some extra helper attributes.\n\n_Provides the following attributes:_\n\n`filter` dictionary property\n\nYou can define a django filter to list only the item you want.\nBy default, all model objects will be listed.\n\n`filters_get` dictionary property\n\nThis is an automation to help you define extra filters through the query GET request\nparameters.\nYou can add a query parameter in the form of `filter_ + field_name` and the object will\nbe filtered out.\nYou can create more complex scenarios by overwriting this behaviour.\n\n`instances` context property\n\nThis property will return all filtered objects and is ready to use inside your\ntemplate file, using `{{ instances }}` variable.\nIn combines `filter` dictionary and `filters_get` dictionary, as described above. \n\n#### *django_htmx_ui.views.crud.*__CrudUpdateMixin__ (InstanceMixin, CrudMixin)\n\nAdd this Mixin to your `TemplateView` classes to add the object update functionality.\nIt basically combines the `CrudMixin` and the `InstanceMixin` mixnins.\n\n#### *django_htmx_ui.views.crud.*__CrudDisplayMixin__ (InstanceMixin, CrudMixin)\n\nAdd this Mixin to your `TemplateView` classes to add the object display functionality.\nIt basically combines the `CrudMixin` and the `InstanceMixin` mixnins.\n\n#### *django_htmx_ui.views.crud.*__CrudActionMixin__ (InstanceMixin, CrudMixin)\n\nAdd this Mixin to your `TemplateView` classes to add the object action functionality.\nIt basically combines the `ResponseNoContentMixin`, `CrudMixin`\nand the `InstanceMixin` mixnins.\nIt can be used to build custom object actions, according to your specific needs. \n\n#### *django_htmx_ui.views.crud.*__CrudDeleteMixin__ (CrudActionMixin)\n\nAdd this Mixin to your `TemplateView` classes to add the object delete functionality.\nIt basically is a `CrudActionMixin` subclass to implement the delete function,\nwhich is the most common action in an object based on the CRUD modeling.\n\nIf you send a http POST in this view, the object will be deleted using the\n`self.instance.delete()` django's function and a success or invalid message will be set.\nYou can alter these behaviours by overwriting `on_post`, `on_post_success_message` and\n`on_post_invalid_message` attributes.\n\n### Mixins\n\nThe following Mixins are available to automate some common scenarios.\nFeel free to extend them more or overwriting the attributes.\n\n#### *django_htmx_ui.views.mixins.*__OriginTemplateMixin__\n\nAdd this Mixin in your `TemplateView` for the view to be accessible directly from\na browser HTTP request and via a htmx request.\nYou can also set the `push_url` attribute to `False`. In that case, the URL will be\nreplaces in the browser's bar but no history will be creared (`HX-Replace` header).\nYou can also set the `push_url` attribute to `None`. In that case, the URL will not\nbe replaced in the browser's bar.\n\n#### *django_htmx_ui.views.mixins.*__PartialTemplateMixin__\n\nAdd this Mixin in your `TemplateView` for the view to be only accessible via a htmx\nrequest.\nBy default, if the url of view is called directly from the browser (outside htmx call),\na redirection will happen to the `/` route path.\nYou can overwrite the default redirection route path by defining the `redirect_partial`\nattribute of the view.\n\n#### *django_htmx_ui.views.mixins.*__FormMixin__\n\nAdd this Mixin in your `TemplateView`, if the view contains a form.\nYou can define a `Form` class inside the `TemplateView` class, which is recommended to\nbe a subclass of django's `Form` or `ModelForm` or any other similar kind.\n\nFor example:\n\n    class MyView(PrivateTemplateView):\n\n        class Form(forms.Form):\n            user = forms.CharField()\n            password = forms.CharField()\n\nOr as a ModelForm:\n\n    class MyView(PrivateTemplateView):\n\n        class Form(forms.ModelForm):\n\n            class Meta:\n                model = MyModel\n                fields = ['field1', 'field2']\n\nAlso, when a POST http request is made, `FormMixIn` will automatically test the form.\n\nIf the form is in a valid state, the `on_post` method will call\n* the `save()` method of the form\n* the `on_post_success_message` method, so you can overwrite it\n* the `on_post_success` method, so you can overwrite it\n\nIf the form is not in a valid state, the `on_post` method will call:\n*  the `on_post_invalid_message` method, so you can overwrite it\n*  the `on_post_invalid` method, so you can overwrite it\n\n_Provides the following attributes:_\n\n`form` context cached property\n\nUse this property as a variable `{{ form }}` in your template file to refer at the form\ninstance and print the form.\nYou can also overwrite the property in your `TemplateView` class, in order to change\nthe attributes of the instance of the form.\n\n`form_instance` property\n\nThis attribute defines the django form's instance parameter, if using a `forms.ModelForm`.\nBy default, gets its value from the instance property, if it is available.\n\n#### *django_htmx_ui.views.mixins.*__InstanceMixin__ (FormMixin)\n\nAdd this Mixin in your `TemplateView`, if the view contains a model form.\nSee `FormMixin` attributes, as this Mixin is a subclass.\n\n_Provides the following attributes:_\n\n`path_route` class property\n\nIt extends the path route url to include automatically the primary key (pk field) of the\nmodel instance, in the form of `'(?P\u003cpk\u003e\\w+)/' + super().path_route`.\nYou can overwrite this class property to describe your own.\n\n`instance` context cached property\n\nIt returns the model object of the instance, reading the pk field from the url path.\n\n`instance_slug` property\n\nIt returns a unique slug for the instance.\n\n`title` context property\n\nIt returns the view title, taken from the string representation of the model's instance.\n\n`on_post_success_message` method\n\nSets a \"'Instance' saved\" message, when the form is successfully saved.\n\n`on_post_success_message` method\n\nSets a \"'Instance' not saved\" message, when the form is not valid.\n\n#### *django_htmx_ui.views.mixins.*__ResponseNoContentMixin__\n\nAdd this Mixin in your `TemplateView` to return `HTTP 204 No Content` as a response.\nNo template rendering will happen.\n\n#### *django_htmx_ui.views.mixins.*__TabsMixin__\n\nIt is common sometimes to use Tabs (subpages) in your project.\nAdd this Mixin in your `TemplateView` to implement tabs' functionality.\n\nYou can use the subclass `Tab` and its subclass `Link` to define your `tabs` atttribute:\n\n    @ContextCachedProperty\n    def tabs(self):\n        return self.Tabs(\n            self.Tabs.Link(\n                title='First tab',\n                url=self.url(FirstTabView),\n                slug='first_tab',\n            ),\n            self.Tabs.Link(\n                title='Second Tab',\n                url=self.url(SecondTabView),\n                slug='second_tab',\n            ),\n            remember=True,\n        )\n\nThen you can use the `{{ tabs }}` variable to print your tabs.\nThe `Tabs` class provides the following attributes to use in your template file:\n\n* `active`: the active tab `Link` object\n* `selected`: the selected index as a number representation, stating from 0\n* `remember`: boolean option, if you want the last tab clicked to be remembered\n              automatically and be activated the next time, using a django session\n* `links`: a list of all links in the `Tabs` object, with the following attributes:\n  * `index`: the index number of the link, starting from 0 for the first link\n  * `title`: the title of the link/tab\n  * `url`: the url of the link/tab\n  * `slug`: the slug of the link/tab\n\n_Provides the following attributes:_\n\n`slug_tab` class property\n\nA unique slug for the tab.\n\n`tab_query_var` property\n\nThe query keyword used on the GET request to display the selected tab.\nBy default, it used the `slug_tab` attribute.\n\n`path_route` class property\n\nThe `path_route` to push or replace on the location_bar.\nThis will only be pushed or replaced when the active link has a slug.\nBy default, it binds to `super().path_route + f'(?:(?P\u003c{cls.slug_tab}\u003e\\w+)/)?'`\n\n#### *django_htmx_ui.views.mixins.*__ModalMixin__\n\nIt is common sometimes to use Modals in your project.\nAdd this Mixin in your `TemplateView` to implement a modal functionality.\n\nYou can use the subclass `Modal` to define your `modal_*` atttribute:\n\n    @ContextCachedProperty\n    def modal_create(self):\n        return self.Modal(\n            url=self.url(Create).query(event=self.request.GET.get('event')),\n        )\n\nIn this view a `{{ modal_create }}` variable will be available in your template.\nYou can basically use the two attributes defined:\n\n* `url`: the htmx url to load inside your modal\n* `id`: a unique id for your modal, which is basically `modal_` + `self.slug_global`\n\n### Utils\n\n#### Utils Classes\n\n`Url` class\n\nThis class represents an `Url` model you can use inside your views controller class or\nin your templates files.\nIt converts to a url string automatically if you pass it through str() or use it inside\na `{{ url }}` brackets variable.\n\n_Provides the following attributes:_\n\n`__init__` (path, query_list) method\n\nYou can initialize a `Url` object by providing a path string and a query_list in the\nform of tuples (name, value).\n\n`__call__` (path=None, query_list=None) method\n\nYou can alter the path or the query_list or both as needed if you call the object again.\n\n`path` string\n\nThe string of the url's path.\n\n`query` Url.Query object\n\nSee below for the attributes provided.\n\n`resolver_match` property\n\nReturns the django's `ResolverMatch` object for the path.\n\n`view` property\n\nReturns the `TemplateView` class, provided by the `resolver_match` above.\nUsually, it will be the view that resolves to the `Url` object.\n\n`Url.Query` class\n\nThis class represents an `Query` model you can use inside your views controller class or\nin your templates files to alter the query part of the `Url`. It automatically built\nby the `Url` object and is ready to use as sub-object / attribute inside.\n\nPlease be aware that the query consists of a list of tupled variables (name, value).\nSo, the same name can be represented more than once.\nThis is a standard behaviour of the url's query.\nAlthough, if you provide a kwargs directory (name, value) this name will become unique.\n\n_Provides the following attributes:_\n\n`reset` (*args, **kwargs) method\n\nBuilds from scratch the query_list based on args list tuples (name, value) and\nthe kwargs dictionary.\n\n`set` (query_list) method\n\nReplaces the query_list with the list provided in the method parameter.\n\n`__call__` (*args, **kwargs) method  \n`add` (*args, **kwargs) method  \n\n* Appends all `args` tuples (name, value) in the query_list.\n* Updates all `kwargs` named values. If name exists, it removes first all instances. \n\n`remove` (name)\n\nRemoves any instances of `name` in the query_list.\n\n`update` (**kwargs)\n\nUpdates all `kwargs` named values. If name exists, it removes first all instances. \n\n`UrlView` class\n\nThis is basically a wrapper of the `Url` class mentioned above, to represent a view.\nIt passes through the attributes `path` and `query` to the `Url` sub-object.\n\n_Provides the following attributes:_\n\n`__init__` (view, *args, **kwargs) method\n`__call__` (view=None, *args, **kwargs) method\n\nDefines the view that will represent the `Url` object.\n\nThe `view` parameter can be in the form of:\n* named view, like `app_name:module_a:my_view`\n* python path of the class child `TemplateView`, like `app_name.views.module_a.MyView`\n* any class child of `TemplateView`\n* any instance of `TemplateView`\n\nThe `*args` and `**kwargs` parameters, represents the url path parameters (if any).\nThese parameters are described in the `path` or `re_path` functions. \n\n`update` (*args, **kwargs) method\n\nUpdates the url path parameters.\n\n`path` property\n\nPassed to the `Url.path` sub-object, see details above.\n\n`query` property\n\nPassed to the `Url.Query` sub-object, see details above.\n\n`Location` class\n\nThis class is a subclass of `Url` class, representing a location object that can be\nread by any path string in the request process, like the browser's location bar,\nor the location derived from the request itself.\n\n`__init__` (path, query_list, push=False) method\n`__call__` (path=None, query_list=None, push=False) method\n\nInitializes or updates the `Url` object (see details above for the parameters `path` and\n`query_list`).\nThe `push` parameter is a flag to be used optionally to remember / set if the engine\nwill push this location back to the browser's url location bar.\n\n`resolver_match` property\n\nThis returns a resolver django's object, representing the url view resolved path.\n\n`create_from_url` class method\n\nThis class method creates a `Location` object from a url string.\n\n#### Utils Methods\n\n`collect_paths`(module, app_name) method\n\nUse this method to collect the paths of the `TemplateView` classed inside a module.\nThe app_name is the name of the application the path belongs to.\nThis method will automatically add:\n* an application namespace (e.g. `app_name`)\n* followed by a module namespace, derived by:\n  * module's `SLUG` attribute, if applicable (e.g. `module_a.SLUG`), and if not\n  * the name of the module (e.g. module_a.py has a name of `module_a`)\n* followed by the `slug` attribute of the `TemplateView` (e.g. `MyView.slug`)\n\nSo the final full-name django's internal view name will be `app_name:module_a:my_view`\n\nYou can anytime refer to this view name and use all django standard calls.\nFor example, use the `reverse` method like this: `reverse('app_name:module_a:my_view')`.\n\nFor more info, how to use the collect_paths inside the django's `urls.py` file,\nsee the `Defining views` section above.\n\n`to_snake_case`(name) method\n\nConverts a string (name) from `CamelCase` to `snake_case`. \n\n`to_camel_case`(name) method\n\nConverts a string (name) from `snake_case` to `CamelCase`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikalexis%2Fdjango_htmx_ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikalexis%2Fdjango_htmx_ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikalexis%2Fdjango_htmx_ui/lists"}