# Django Modal Actions
Django Modal Actions is a reusable Django app that provides a convenient way to add modal-based actions to your Django admin interface. It allows you to create custom actions that open in a modal dialog, enhancing the user experience and functionality of your Django admin.
<p float="left">
<img src="screenshots/modal_action_example1.png" width="49%" />
<img src="screenshots/modal_action_example2.png" width="49%" />
</p>
## Features
- Easy integration with Django admin
- Support for both list-view and object-view actions
- Customizable modal forms
- AJAX-based form submission
## Requirements
- Python (>= 3.7)
- Django (>= 3.2)
## Installation
1. Install the package using pip:
```
pip install django-modal-actions
```
2. Add `'django_modal_actions'` to your `INSTALLED_APPS` setting:
```python
INSTALLED_APPS = [
...
'django_modal_actions',
...
]
```
## Usage
1. In your `admin.py`, import the necessary components:
```python
from django.contrib import admin
from django_modal_actions import ModalActionMixin, modal_action
```
2. Create a custom admin class that inherits from `ModalActionMixin` and your base admin class:
```python
@admin.register(YourModel)
class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):
list_display = ['name', 'status']
modal_actions = ["approve"]
list_modal_actions = ["bulk_approve"]
@modal_action(
modal_header="Approve Item",
modal_description="Are you sure you want to approve this item?"
)
def approve(self, request, obj, form_data=None):
obj.status = 'approved'
obj.save()
return f"{obj} has been approved."
@modal_action(
modal_header="Bulk Approve",
modal_description="Are you sure you want to approve the selected items?"
)
def bulk_approve(self, request, queryset, form_data=None):
count = queryset.update(status='approved')
return f"{count} items have been approved."
```
3. If you need a custom form for your action, create a form class:
```python
from django import forms
class ApprovalForm(forms.Form):
reason = forms.CharField(label="Approval Reason", required=True, widget=forms.Textarea)
def clean_reason(self):
reason = self.cleaned_data["reason"]
if len(reason) < 10:
raise forms.ValidationError("Reason must be at least 10 characters long")
return reason
```
Then, use it in your action:
```python
@modal_action(
modal_header="Approve with Reason",
modal_description="Please provide a reason for approval",
form_class=ApprovalForm
)
def approve_with_reason(self, request, obj, form_data=None):
obj.status = 'approved'
obj.approval_reason = form_data['reason']
obj.save()
return f"{obj} has been approved with reason: {form_data['reason']}"
```
## Permissions Example
You can add custom permission checks to your modal actions using the `permissions` parameter of the `modal_action` decorator. Here's an example:
```python
from django.contrib import admin
from django_modal_actions import ModalActionMixin, modal_action
from .models import YourModel
def can_approve(request, obj=None):
return request.user.has_perm('yourapp.can_approve_items')
@admin.register(YourModel)
class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):
list_display = ['name', 'status']
modal_actions = ['approve']
@modal_action(
modal_header="Approve Item",
modal_description="Are you sure you want to approve this item?",
permissions=can_approve
)
def approve(self, request, obj, form_data=None):
obj.status = 'approved'
obj.save()
return f"{obj} has been approved."
```
In this example, the `can_approve` function checks if the user has the `can_approve_items` permission. The `approve` action will only be available to users who have this permission.
You can also use multiple permission checks by passing a list of functions:
```python
def is_staff(request, obj=None):
return request.user.is_staff
@modal_action(
modal_header="Approve Item",
modal_description="Are you sure you want to approve this item?",
permissions=[can_approve, is_staff]
)
def approve(self, request, obj, form_data=None):
obj.status = 'approved'
obj.save()
return f"{obj} has been approved."
```
In this case, the user must both have the `can_approve_items` permission and be a staff member to see and use the approve action.
## Custom Admin Templates
If you need to customize the admin templates while still using the modal actions, you can override the `change_form_template` and `change_list_template` in your ModelAdmin class. Here's how to do it:
1. In your `admin.py`, add the `change_form_template` or `change_list_template` attribute to your ModelAdmin class:
```python
@admin.register(YourModel)
class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):
change_form_template = 'admin/yourapp/yourmodel/change_form.html'
change_list_template = 'admin/yourapp/yourmodel/change_list.html'
# ... rest of your ModelAdmin code
```
2. Create the custom template files in your app's template directory. For example:
```
yourapp/
└── templates/
└── admin/
└── yourapp/
└── yourmodel/
├── change_form.html
└── change_list.html
```
3. In your custom templates, extend the default admin templates and add the modal action buttons. Here's an example for `change_form.html`:
```html
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools %}
<ul class="object-tools">
{% block object-tools-items %}
{{ block.super }}
{% if modal_action_buttons %}
<li>{{ modal_action_buttons }}</li>
{% endif %}
{% endblock %}
</ul>
{% endblock %}
```
And for `change_list.html`:
```html
{% extends "admin/change_list.html" %}
{% load i18n admin_urls %}
{% block object-tools %}
<ul class="object-tools">
{% block object-tools-items %}
{{ block.super }}
{% if list_modal_action_buttons %}
<li>{{ list_modal_action_buttons }}</li>
{% endif %}
{% endblock %}
</ul>
{% endblock %}
```
These custom templates will include the modal action buttons while allowing you to make other customizations to your admin interface.
## Testing
To run the tests, execute:
```
python -m unittest discover django_modal_actions/tests
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License.
Raw data
{
"_id": null,
"home_page": "https://github.com/Mng-dev-ai/django-modal-actions",
"name": "django-modal-actions",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": null,
"author": "Michael Gendy",
"author_email": "nagymichel13@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/97/35/88c82f03a6a1b6e4931bb1e295ce139c7919dc6cf58401f91f2872e60a47/django_modal_actions-0.1.2.tar.gz",
"platform": null,
"description": "# Django Modal Actions\n\nDjango Modal Actions is a reusable Django app that provides a convenient way to add modal-based actions to your Django admin interface. It allows you to create custom actions that open in a modal dialog, enhancing the user experience and functionality of your Django admin.\n\n<p float=\"left\">\n <img src=\"screenshots/modal_action_example1.png\" width=\"49%\" />\n <img src=\"screenshots/modal_action_example2.png\" width=\"49%\" /> \n</p>\n\n## Features\n\n- Easy integration with Django admin\n- Support for both list-view and object-view actions\n- Customizable modal forms\n- AJAX-based form submission\n\n## Requirements\n\n- Python (>= 3.7)\n- Django (>= 3.2)\n\n## Installation\n\n1. Install the package using pip:\n\n ```\n pip install django-modal-actions\n ```\n\n2. Add `'django_modal_actions'` to your `INSTALLED_APPS` setting:\n ```python\n INSTALLED_APPS = [\n ...\n 'django_modal_actions',\n ...\n ]\n ```\n\n## Usage\n\n1. In your `admin.py`, import the necessary components:\n\n ```python\n from django.contrib import admin\n from django_modal_actions import ModalActionMixin, modal_action\n ```\n\n2. Create a custom admin class that inherits from `ModalActionMixin` and your base admin class:\n\n ```python\n @admin.register(YourModel)\n class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):\n list_display = ['name', 'status']\n modal_actions = [\"approve\"]\n list_modal_actions = [\"bulk_approve\"]\n\n @modal_action(\n modal_header=\"Approve Item\",\n modal_description=\"Are you sure you want to approve this item?\"\n )\n def approve(self, request, obj, form_data=None):\n obj.status = 'approved'\n obj.save()\n return f\"{obj} has been approved.\"\n\n @modal_action(\n modal_header=\"Bulk Approve\",\n modal_description=\"Are you sure you want to approve the selected items?\"\n )\n def bulk_approve(self, request, queryset, form_data=None):\n count = queryset.update(status='approved')\n return f\"{count} items have been approved.\"\n ```\n\n3. If you need a custom form for your action, create a form class:\n\n ```python\n from django import forms\n\n class ApprovalForm(forms.Form):\n reason = forms.CharField(label=\"Approval Reason\", required=True, widget=forms.Textarea)\n\n def clean_reason(self):\n reason = self.cleaned_data[\"reason\"]\n if len(reason) < 10:\n raise forms.ValidationError(\"Reason must be at least 10 characters long\")\n return reason\n ```\n\n Then, use it in your action:\n\n ```python\n @modal_action(\n modal_header=\"Approve with Reason\",\n modal_description=\"Please provide a reason for approval\",\n form_class=ApprovalForm\n )\n def approve_with_reason(self, request, obj, form_data=None):\n obj.status = 'approved'\n obj.approval_reason = form_data['reason']\n obj.save()\n return f\"{obj} has been approved with reason: {form_data['reason']}\"\n ```\n\n## Permissions Example\n\nYou can add custom permission checks to your modal actions using the `permissions` parameter of the `modal_action` decorator. Here's an example:\n\n```python\nfrom django.contrib import admin\nfrom django_modal_actions import ModalActionMixin, modal_action\nfrom .models import YourModel\n\ndef can_approve(request, obj=None):\n return request.user.has_perm('yourapp.can_approve_items')\n\n@admin.register(YourModel)\nclass YourModelAdmin(ModalActionMixin, admin.ModelAdmin):\n list_display = ['name', 'status']\n modal_actions = ['approve']\n\n @modal_action(\n modal_header=\"Approve Item\",\n modal_description=\"Are you sure you want to approve this item?\",\n permissions=can_approve\n )\n def approve(self, request, obj, form_data=None):\n obj.status = 'approved'\n obj.save()\n return f\"{obj} has been approved.\"\n```\n\nIn this example, the `can_approve` function checks if the user has the `can_approve_items` permission. The `approve` action will only be available to users who have this permission.\n\nYou can also use multiple permission checks by passing a list of functions:\n\n```python\ndef is_staff(request, obj=None):\n return request.user.is_staff\n\n@modal_action(\n modal_header=\"Approve Item\",\n modal_description=\"Are you sure you want to approve this item?\",\n permissions=[can_approve, is_staff]\n)\ndef approve(self, request, obj, form_data=None):\n obj.status = 'approved'\n obj.save()\n return f\"{obj} has been approved.\"\n```\n\nIn this case, the user must both have the `can_approve_items` permission and be a staff member to see and use the approve action.\n\n## Custom Admin Templates\n\nIf you need to customize the admin templates while still using the modal actions, you can override the `change_form_template` and `change_list_template` in your ModelAdmin class. Here's how to do it:\n\n1. In your `admin.py`, add the `change_form_template` or `change_list_template` attribute to your ModelAdmin class:\n\n ```python\n @admin.register(YourModel)\n class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):\n change_form_template = 'admin/yourapp/yourmodel/change_form.html'\n change_list_template = 'admin/yourapp/yourmodel/change_list.html'\n # ... rest of your ModelAdmin code\n ```\n\n2. Create the custom template files in your app's template directory. For example:\n \n ```\n yourapp/\n \u2514\u2500\u2500 templates/\n \u2514\u2500\u2500 admin/\n \u2514\u2500\u2500 yourapp/\n \u2514\u2500\u2500 yourmodel/\n \u251c\u2500\u2500 change_form.html\n \u2514\u2500\u2500 change_list.html\n ```\n\n3. In your custom templates, extend the default admin templates and add the modal action buttons. Here's an example for `change_form.html`:\n\n ```html\n {% extends \"admin/change_form.html\" %}\n {% load i18n admin_urls %}\n\n {% block object-tools %}\n <ul class=\"object-tools\">\n {% block object-tools-items %}\n {{ block.super }}\n {% if modal_action_buttons %}\n <li>{{ modal_action_buttons }}</li>\n {% endif %}\n {% endblock %}\n </ul>\n {% endblock %}\n ```\n\n And for `change_list.html`:\n\n ```html\n {% extends \"admin/change_list.html\" %}\n {% load i18n admin_urls %}\n\n {% block object-tools %}\n <ul class=\"object-tools\">\n {% block object-tools-items %}\n {{ block.super }}\n {% if list_modal_action_buttons %}\n <li>{{ list_modal_action_buttons }}</li>\n {% endif %}\n {% endblock %}\n </ul>\n {% endblock %}\n ```\n\nThese custom templates will include the modal action buttons while allowing you to make other customizations to your admin interface.\n\n## Testing\n\nTo run the tests, execute:\n\n```\npython -m unittest discover django_modal_actions/tests\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Django app for adding modal actions to the admin interface",
"version": "0.1.2",
"project_urls": {
"Homepage": "https://github.com/Mng-dev-ai/django-modal-actions"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fe274f5463a9da24d6a6440404e89d5768a2b6f8d7af145f7b4ea3141c86c20f",
"md5": "1e92e4aa11f9c4addf22eacdf3d3c0b8",
"sha256": "ce387a03e34e24cd7dee555d435c8e300de863c109033266a2411258f0a60c6a"
},
"downloads": -1,
"filename": "django_modal_actions-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1e92e4aa11f9c4addf22eacdf3d3c0b8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 16573,
"upload_time": "2024-09-08T17:21:33",
"upload_time_iso_8601": "2024-09-08T17:21:33.945432Z",
"url": "https://files.pythonhosted.org/packages/fe/27/4f5463a9da24d6a6440404e89d5768a2b6f8d7af145f7b4ea3141c86c20f/django_modal_actions-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "973588c82f03a6a1b6e4931bb1e295ce139c7919dc6cf58401f91f2872e60a47",
"md5": "b3db3fdecb66e8d72ba335384d676952",
"sha256": "67bc7914130934886325f6518013d45836d1fcfdb8135068e8e6dac7c51f2862"
},
"downloads": -1,
"filename": "django_modal_actions-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "b3db3fdecb66e8d72ba335384d676952",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 15637,
"upload_time": "2024-09-08T17:21:36",
"upload_time_iso_8601": "2024-09-08T17:21:36.139970Z",
"url": "https://files.pythonhosted.org/packages/97/35/88c82f03a6a1b6e4931bb1e295ce139c7919dc6cf58401f91f2872e60a47/django_modal_actions-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-08 17:21:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Mng-dev-ai",
"github_project": "django-modal-actions",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "django-modal-actions"
}