From d5b8d1b36838aa9db08f21cee06510b9b5bf0d5f Mon Sep 17 00:00:00 2001
From: michalpokusa <72110769+michalpokusa@users.noreply.github.com>
Date: Mon, 23 Sep 2024 23:27:06 +0000
Subject: [PATCH] Reordered method definitions on `ActionForm` and updated
README.md
---
README.md | 54 ++++++++++++++++++++++++++++--
django_admin_action_forms/forms.py | 28 ++++++++--------
2 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 4288fd6..3c71624 100644
--- a/README.md
+++ b/README.md
@@ -263,9 +263,28 @@ def custom_action(self, request, queryset, data):
Base class for creating action forms responsible for all under the hood logic. Nearly always you will want to subclass `AdminActionForm` instead of `ActionForm`, as it provides additional features.
+#### _def_ \_\_post_init\_\_(modeladmin, request, queryset)
+
+> _Added in version 1.2.0_
+
+Method called after the form is initialized that can be used to modify the form fields, add additional ones or change the form's `Meta` options based on the `modeladmin` from which the action was called, `request` and `queryset` containing objects on which the action will be performed.
+
+```python
+def __post_init__(self, modeladmin, request, queryset):
+ modeladmin.message_user(
+ request, f"Warning, this action cannot be undone.", "warning"
+ )
+
+ if request.user.is_superuser:
+ self.fields["field1"].required = False
+
+ if queryset.count() > 25:
+ self.Meta.list_objects = False
+```
+
### AdminActionForm
-In addition to `ActionForm`, it replaces default text inputs for `DateField`, `TimeField`, `SplitDateTimeField` with respective admin widgets.
+In addition to `ActionForm`, it replaces default widgets for most field types with corresponding Django admin widgets that e.g. add a interactive date picker or prepend a clickable link above URL fields.
Most of the time this is a class you want to subclass when creating custom action forms.
@@ -344,7 +363,7 @@ Specifies the fields that should be displayed in the form. If `fieldsets` is pro
fields = ["field1", ("field2", "field3")]
```
-#### get_fields(request)
+#### _def_ get_fields(request)
> Works similar to
ModelAdmin.get_fields()
@@ -391,7 +410,7 @@ fieldsets = [
]
```
-#### get_fieldsets(request)
+#### _def_ get_fieldsets(request)
> Works similar to
ModelAdmin.get_fieldsets()
@@ -480,3 +499,32 @@ autocomplete_fields = ["field1", "field2"]
> [!NOTE]
> Autocomplete requires including `'django_admin_action_forms.urls'` in your `urls.py` file.
> See [🔌 Instalation](#-instalation).
+
+
+#### confirm_button_text
+
+> _Added in version 1.2.0_
+
+Default: `"Confirm"`
+
+Text displayed on the confirm button. It can be either a `str` or a lazy translation.
+
+```python
+from django.utils.translation import gettext_lazy as _
+
+confirm_button_text = _("Proceed")
+```
+
+#### cancel_button_text
+
+> _Added in version 1.2.0_
+
+Default: `"Cancel"`
+
+Text displayed on the cancel button. It can be either a `str` or a lazy translation.
+
+```python
+from django.utils.translation import gettext_lazy as _
+
+cancel_button_text = _("Abort")
+```
diff --git a/django_admin_action_forms/forms.py b/django_admin_action_forms/forms.py
index dac8aa8..9b61069 100644
--- a/django_admin_action_forms/forms.py
+++ b/django_admin_action_forms/forms.py
@@ -51,6 +51,20 @@ def _convert_from_form_to_actionform(self, request: HttpRequest) -> None:
self._apply_limit_choices_to_on_model_choice_fields()
self._replace_widgets_for_filter_and_autocomplete_fields()
+ def _remove_excluded_fields(self, request: HttpRequest) -> None:
+ for field_name in self._get_excluded_fields(request):
+ self.fields.pop(field_name)
+
+ def _apply_limit_choices_to_on_model_choice_fields(self) -> None:
+ for field in self.fields.values():
+ if isinstance(field, (ModelChoiceField, ModelMultipleChoiceField)):
+ queryset: QuerySet = field.queryset
+
+ limit_choices_to = field.get_limit_choices_to()
+
+ if limit_choices_to is not None:
+ field.queryset = queryset.complex_filter(limit_choices_to)
+
def _replace_widgets_for_filter_and_autocomplete_fields(self) -> None:
meta: ActionForm.Meta = getattr(self, "Meta", None)
autocomplete_fields = getattr(meta, "autocomplete_fields", [])
@@ -145,20 +159,6 @@ def _get_excluded_fields(self, request: HttpRequest) -> "set[str]":
return all_fields.difference(included_fields)
- def _remove_excluded_fields(self, request: HttpRequest) -> None:
- for field_name in self._get_excluded_fields(request):
- self.fields.pop(field_name)
-
- def _apply_limit_choices_to_on_model_choice_fields(self) -> None:
- for field in self.fields.values():
- if isinstance(field, (ModelChoiceField, ModelMultipleChoiceField)):
- queryset: QuerySet = field.queryset
-
- limit_choices_to = field.get_limit_choices_to()
-
- if limit_choices_to is not None:
- field.queryset = queryset.complex_filter(limit_choices_to)
-
class Meta:
list_objects: bool
help_text: str