conjunto
¶
Django application framework/helpers using HTMX, tabler.io, tables2, crispy-forms & more.
conjunto.cms
¶
conjunto.components
¶
DataGrid
¶
Bases: Component
The DataGrid class is a component that generates a data grid for displaying data
in a tabular format.
It automatically determines all regular model fields and shows their translated title. It also detects properties/getters instead of fields, the component tries to find out a proper name as title here by creating a capitalized version of the property name and translating it into the locale language. However, you have to provide a proper translation string for your property name in your .po file manually.
Note To keep Django's
makemessagesfrom commenting out these "unused" translations, just add an unused_("...")string anywhere into your method. E.g. when your property is named "display_name()", just add a_("Display name")anywhere into this method block. This keeps Django from garbage collecting this translation.
| Attributes: |
|
|---|
Example usage:
{% #datagrid object=request.user fields="first_name,last_name,email" %}
get_context_data(**kwargs)
¶
renders fields of given object in a datagrid-usable form.
List
¶
Bases: Component
A flexible component to display a Tabler.io list.
| Attributes: |
|
|---|
Updateable
¶
Bases: Component
HTML element that updates itself using HTMX when a certain Javascript event is triggerd anywhere in the body.
| Attributes: |
|
|---|
Example
{% updateable id="my-card" trigger="person:changed" url=request.path %}
{% url 'person:update' as person_update_url %}
{% updateable elt="ul" id="people-list" trigger="person:changed" url=person_update_url %}
conjunto.context_processors
¶
conjunto.forms
¶
DynamicHtmxFormMixin
¶
Bases: DynamicFormMixin
Mixin class for creating dynamic forms with HTMX.
This mixin extends the functionality of the DynamicFormMixin by adding htmx attributes to the form fields that can be used for triggering dynamic updates.
| Attributes: |
|
|---|
| Raises: |
|
|---|
fields_required(fields, msg=None)
¶
Helper method used for conditionally marking fields as required.
| Parameters: |
|
|---|
Example usage:
def clean(self):
is_person = self.cleaned_data.get("is_person")
if is_person:
self.field_required(["first_name", "last_name"])
self.field_required("title", "A title is definitely required here.")
self.field_required(["age", "size"], "You forgot this field.")
else:
self.cleaned_data["first_name"] = ""
self.cleaned_data["last_name"] = ""
self.cleaned_data["title"] = ""
return self.cleaned_data
Credits go to https://www.fusionbox.com/blog/detail/creating-conditionally-required-fields-in-django-forms/577/
ErrorLogMixin
¶
A mixin that can be added to a Form during development/debugging, so that it logs all form errors.
MyDynamicFormMixin
¶
A mixin class for Django forms that allows dynamic fields to be included or excluded based on certain conditions.
| Attributes: |
|
|---|
conjunto.htmx
¶
HxActionButton
¶
Bases: HxButton
A renderable action button from an IActionButton instance.
| Parameters: |
|
|---|
HxButton
¶
Render a HTMX enabled button.
| Attributes: |
|
|---|
Example
{% hx_button url="person:add" method="post" icon="plus" dialog=True css_class="btn"
HxLink
¶
Render a hyperlink using HTMX.
| Attributes: |
|
|---|
IHtmxComponentMixin
¶
Bases: HtmxResponseMixin
An interface Mixin that describes a component and can be rendered as plugin.
- Declare an interface for HTMX components
- Declare Implementations of that interface which also inherit from
View.
Examples:
# in your plugin's api/interfaces.py, create an interface for your view
@Interface
class IUserProfileSection(IHtmxComponentMixin, ...):
params = ["pk"]
template_name = "common/layout/profile_section.html"
...
# in your plugin's views.py
def PasswordView(IUserProfileSection, UpdateView)
...
def OtherComponentView(IUserProfileSection, TemplateView)
...
Use them in your template:
{% for plugin in components.IUserProfileSection %}
<a href="#"
hx-get="{% url component.get_url_name user.id %}"
hx-trigger="{% if component.selected %}load, {% endif %}click once"
{# hx-push-url="{{ component.name }}" #}
hx-target="#profile-content"
class="list-group-item list-group-item-action d-flex align-items-center
active">
<i class="bi bi-{{ component.icon }} me-2"></i>
{{ component.title }}
</a>
{% endfor %}
You can also inherit from other mixins, e.g. PermissionRequiredMixin, etc.
class UserprofilePasswordSection(
IUserProfileSection, PermissionRequiredMixin, TemplateView
):
name = "password"
permission_required = "..."
template_name = "my_app/password_view.html
form_kwargs_request = False
class-attribute
instance-attribute
¶
Should the evtl. attached form receive a request?
group = ''
class-attribute
instance-attribute
¶
The group this component lives under. Can be used to display group headers.
icon: str = ''
class-attribute
instance-attribute
¶
the icon name, if the component is listed in a list, and icons are used.
name: str = ''
class-attribute
instance-attribute
¶
The view name of the component. Must be unique. Used in and URLs. Can be used for HTML attributes.
params: list[str] = []
class-attribute
instance-attribute
¶
A list of params the view is using. These must then be passed when calling the view from a template, e.g. via hx-get.
title: str = ''
class-attribute
instance-attribute
¶
The title this plugin is rendered with. It's up to you how the plugin uses that title.
weight: int = 0
class-attribute
instance-attribute
¶
The weight this component is ranked like menu items. The more weight, the more the component sinks "down" in the list.
enabled()
¶
Hook for implementations to define if the component is enabled.
| Returns: |
|
|---|
get_name()
¶
Returns the component's view (machine) name.
get_title()
¶
returns the component's title.
Use it in templates like {{ component.get_title }}
get_url_name()
¶
Returns the component's url.'
Use it as {% url component.get_url ... %} in a template.
get_url_patterns()
classmethod
¶
Convenience method to add to your urls.py in an include section:
Example
url_patterns = [
path(...),
path("profile/",
include(
(IUserProfileSectionView.get_url_patterns(), "profile"),
namespace="profile"
)
),
]
# or directly add the url_patterns to the main list:
url_patterns += IUserProfileSectionView.get_url_patterns()
get_urlpattern()
¶
Calculates the urlpattern where this component is accessible.
That can be used e.g. in hx-get attributes. Returns: a URLPattern that can be used in your urls.py
Icon
¶
Render an icon using Bootstrap 5.
| Attributes: |
|
|---|
UseComponentMixin
¶
A mixin that can be added to a View that uses HTMX components.
This can be used if e.g. a View has tabs, or variable parts of the page
that are extended by a component. The URL is pushed automatically with the new
component as configurable GET parameter, e.g.: example.com/persons/42?tab=account
Example
class MyView(UseComponentMixin, DetailView):
components = [PersonAccountTab]
| Attributes: |
|
|---|
query_variable = 'tab'
class-attribute
instance-attribute
¶
The query variable that is used to indicate the active component.
conjunto.http
¶
HttpResponseEmpty
¶
Bases: HttpResponse
An HTTP response that has no content.
Used for HTMX requests that should not return anything, like delete requests. The returned status code is 204.
HttpResponseHXRedirect
¶
Bases: HttpResponseRedirect
A Http response that redirects a HTMX request to the location given in
redirect_to
conjunto.management
¶
commands
¶
update_permissions
¶
Command
¶
Bases: Command
Reload permissions of all (given) apps.
Checks all (given) apps for a group_permissions attribute and creates Group permissions using that schema.
# apps.py
import ...
class MyPackageCppConfig(AppConfig):
group_permissions: {
"Authors": { my_package.MyContentTypeModel: ["view", "change"],
# on my special site, admins may not change content, just add/delete it!
"Site admins": { "my_package.MyContentTypeModel": ["view", "add", "delete"],
}
conjunto.menu
¶
IActionButton
¶
Bases: MenuItemInterfaceMixin
An action button that can be added to an e.g. table row.
| Attributes: |
|
|---|
IMenuItem
¶
Bases: MenuItemInterfaceMixin
An extendable and versatile MenuItem Interface
You can use that for creating menu items in a named menu:
class AddUserAction(IMenuItem)
menu = "page_actions"
title = _("Add user")
url = reverse_lazy("user:delete")
icon = "user-delete"
| Attributes: |
|
|---|
selected()
¶
Check current URL against this item.
Menu
¶
Represents a named menu during a request.
Usually it is used in Django templates by calling menus.<name>
which then will return all MenuItems with a matching "menu" name
attribute. Therefore, Menu will be instantiated by a context_processor,
so that the menu variable in the template
<ul>
{% for item in menus.user %}
<li><a href="{{item.url}}">{{ item.title }}</a></li>
{% endfor %}
</ul>
__getitem__(item)
¶
Returns filtered out menu items with the given '.menu' name.
MenuItemInterfaceMixin
¶
A mixin that provides common functionality for menu items or action buttons etc.
| Attributes: |
|
|---|
__getattr__(item)
¶
For all attrs that are requested in the template and are not defined in the class, don't produce an error, just return an empty string.
children()
¶
Returns an iterable of all children of this menu item.
filter(name)
classmethod
¶
Filter the menu items by the 'menu' key name.
has_children()
¶
Returns True if this menu item has children, False otherwise.
has_parent()
¶
Returns True if this menu item has a parent, False otherwise.
conjunto.middleware
¶
HtmxMessageMiddleware
¶
Filters out django messages and puts them in to the HX-Trigger header if current request is a HTMX request
conjunto.models
¶
AbstractSettings
¶
Bases: SingletonModel
Represents the settings of the application.
This model is meant to be subclassed by your application. Please add application specific settings as needed to this model.
Page
¶
Bases: Model
Represents a generic page.
This class is an abstract base class that provides common fields and methods for all page subclasses.
SingletonModel
¶
Bases: Model
Singleton Django Model.
Allow only one instance of the model to be created.
To get the instance of the model, use <YourModel>.get_instance().
get_instance()
classmethod
¶
Load object from the database.
Failing that, create a new empty (default) instance of the object and return it (without saving it - you have to do that yourself).
| Raises: |
|
|---|
save(*args, **kwargs)
¶
Save object to the database.
| Raises: |
|
|---|
conjunto.tables
¶
ActionButtonType
¶
Bases: IntegerChoices
Action buttons type, and their weights.
ActionButtonsTable
¶
Bases: UpdateTableMixin, Table
A table mixin that provides an "actions" column for row actions.
The table will update itself if a given event is triggered. Per default,
the actions column is positioned at the end via Meta.sequence. However,
if you use your own Meta.sequence, don't forget to add the "actions"
column at the end.
| Parameters: |
|
|---|
render_actions(record)
¶
sort all desired buttons (standard and IActionMenu generated) by weight, and render them.
UpdateTableMixin
¶
A table mixin that that updates itself using HTMX when a javascript event is triggered.
conjunto.tools
¶
camel_case2snake(camel_str, separator='_')
¶
Converts a CamelCase string to snake_case.
country_code_from_locale(loc)
¶
Extracts an (uppercase) country code from a locale
country_name_from_code(iso3166_code)
¶
Returns the country name from a ISO 3166 Alpha2 country code.
create_groups_permissions(groups_permissions)
¶
Creates groups and their permissions defined in given groups_permissions
automatically.
| Attributes: |
|
|---|
get_system_locales(strip_c=True)
¶
Finds locales installed on a POSIX system and returns a list.
| Parameters: |
|
|---|
language_from_locale(loc)
¶
Extracts a language code from a locale
snake_case2spaces(string)
¶
Converts a snake_case string to spaces.
spaces2snake_case(string)
¶
Converts a space separated string to snake_case.
str_to_bool(bool_str)
¶
returns True if bool_str is "true", else False.
conjunto.views
¶
AnonymousRequiredMixin
¶
Bases: PermissionRequiredMixin
View mixin that only allows access for anonymous users.
AutoPermissionsViewMixin
¶
Bases: PermissionRequiredMixin
Automatically uses view/create/change/delete permissions for the given model.
It automatically generates the "
| Attributes: |
|
|---|
DialogType
¶
Bases: Enum
Enumeration of possible dialog levels.
Levels are used from Python's logging module
DynamicHtmxFormViewMixin
¶
Bases: PrepopulateFormViewMixin
Mixin class for dynamic form views.
This mixin can be used with any FormView class to automatically prepopulate fields from GET parameters, and adds them to a "context" variable which is available within the form instance.
This view is intended to be used together with DynamicHtmxFormMixin for the
form_class.
It creates a form_id (if not given) and passes it to the form. This is needed as HTMX target id.
GenericLicenseView
¶
Bases: LatestVersionMixin, DetailView
Generic privacy page view that displays the newest LicensePage.
GenericPrivacyView
¶
Bases: LatestVersionMixin, DetailView
Generic privacy page view that displays the newest PrivacyPage.
HtmxDeleteView
¶
Bases: HtmxFormMixin, DeleteView
Enhanced DeleteView that per default returns an empty HttpResponse.
TODO either use success_url, OR success_event.¶
| Attributes: |
|
|---|
HtmxFormMixin
¶
Bases: HtmxResponseMixin
Mixin for a form view that uses HTMX.
Returns an "Hx-Trigger" attribute which triggers a Javascript event on the client.
| Attributes: |
|
|---|
HtmxResponseMixin
¶
View Mixin to add HTMX functionality.
optionally checks if request originates from an HTMX request.
| Attributes: |
|
|---|
| Raises: |
|
|---|
HtmxTemplateMixin
¶
If called from HTMX, this view renders template names with a "_htmx" suffix.
LatestVersionMixin
¶
A mixin for views that require fetching the latest version of an object.
You can override the template in <your_app_name>/versioned_page.html.
| Attributes: |
|
|---|
ModalCreateView
¶
Bases: PermissionRequiredMixin, ModalFormViewMixin, CreateView
Convenience CreateView (with permissions) that lives in a Modal.
It automatically generates the Modal title and sets the "create_
ModalFormViewMixin
¶
Bases: HtmxFormMixin
Mixin for FormViews that should live in a modal.
It relies on crispy-forms intensively, and already provides a form helper instance attribute you can use.
In many cases, you need no template, as this mixin provides a generic one with
a customizable title. The form is generated using crispy-forms.
If you want to customize if further, then, extend "conjunto/modal-form.html".
This template uses a header with a title block, a body,
and a footer block to override, for your modal dialog. In the
footer, there is always a "Cancel" button, and as default, a "Save"
button, which you can override using the "footer" block.
When the modal pops up, the focus is set to the first visible input element.
You can customize the content of the "Save" button by changing the button_content
attribute to another string.
If the form is saved successfully, it returns an empty HttpResponse(204)
and emits the event specified in success_event on the client,
so that it can reload changed content.
autofocus_field = ''
class-attribute
instance-attribute
¶
The field that gets the autofocus when the modal is shown
button_content = _('Save')
class-attribute
instance-attribute
¶
The content of the 'Save' button
dialog_type: DialogType = DialogType.NOTSET
class-attribute
instance-attribute
¶
The type of the dialog: INFO,
form_layout: list = []
class-attribute
instance-attribute
¶
The crispy forms layout for the form
modal_title: str = ''
class-attribute
instance-attribute
¶
The title of the modal form
template_name = 'conjunto/modal-form.html'
class-attribute
instance-attribute
¶
The default template name for the modal form. This template provides a simple modal form. You can extend it in your own templates too.
get_modal_title()
¶
Returns a string that is used as title of the modal.
ModalUpdateView
¶
Bases: _ModalModelViewMixin, UpdateView
Convenience UpdateView (with permissions) that lives in a Modal.
It automatically generates the Modal title and sets the "change_
PrepopulateFormViewMixin
¶
A mixin class that prepopulates form fields with values from the request.GET parameters.
This mixin can be used with any FormView class to automatically prepopulate form fields with values from the URL query string parameters.
Example usage:
class MyFormView(PrepopulateFormMixin, FormView): form_class = MyForm template_name = 'my_template.html' success_url = reverse_lazy('my_success_url')
In the above example, the form fields will be prepopulated with values from the URL query string parameters when the form view is loaded.
get_initial()
¶
Returns the initial data for the form.
clean_dict(input_dict)
¶
Clean the input dictionary by removing any key-value pairs where the value is "undefined".
:param input_dict: The input dictionary to be cleaned. :return: A dictionary with the same keys as the input dictionary, but with the "undefined" values removed.