Skip to content

Commit 7f0d7fa

Browse files
committed
Initial release
0 parents  commit 7f0d7fa

File tree

22 files changed

+1196
-0
lines changed

22 files changed

+1196
-0
lines changed

.github/workflows/CD.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: CD
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
deploy:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: Set up Python
13+
uses: actions/setup-python@v4
14+
with:
15+
python-version: "3.x"
16+
- name: Install dependencies
17+
run: |
18+
python -m pip install --upgrade pip
19+
pip install build twine
20+
- name: Build and publish
21+
env:
22+
TWINE_USERNAME: __token__
23+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
24+
run: |
25+
python -m build
26+
twine upload dist/*

.github/workflows/CI.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Set up Python
15+
uses: actions/setup-python@v4
16+
with:
17+
python-version: 3.9
18+
- name: Install Dependencies
19+
run: |
20+
python -m pip install --upgrade pip
21+
pip install .[dev]
22+
- name: Run Ruff
23+
run: ruff check .
24+
- name: Run Ruff Format
25+
run: ruff format --check .
26+
test:
27+
runs-on: ubuntu-latest
28+
strategy:
29+
max-parallel: 4
30+
matrix:
31+
python-version: [3.7, 3.8, 3.9, "3.10"]
32+
django-version: [3.2, 4.0, 4.1, 4.2]
33+
exclude:
34+
# Django 4.0+ requires Python 3.8+
35+
- python-version: 3.7
36+
django-version: 4.0
37+
- python-version: 3.7
38+
django-version: 4.1
39+
- python-version: 3.7
40+
django-version: 4.2
41+
42+
steps:
43+
- uses: actions/checkout@v2
44+
- name: Set up Python ${{ matrix.python-version }}
45+
uses: actions/setup-python@v2
46+
with:
47+
python-version: ${{ matrix.python-version }}
48+
- name: Install Dependencies
49+
run: |
50+
python -m pip install --upgrade pip
51+
python -m pip install "Django==${{ matrix.django-version }}.*"
52+
python -m pip install selenium webdriver-manager
53+
- name: Run Tests
54+
run: |
55+
python -m unittest discover django_modal_actions/tests

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
*.pyc
2+
__pycache__
3+
.DS_Store
4+
.coverage
5+
.tox/
6+
*.db
7+
*sqlite
8+
.venv
9+
.idea
10+
.env
11+
build/*
12+
dist/*
13+
*.egg-info
14+
.DS_Store

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Version 0.1.0 (September 02, 2024)
2+
3+
---
4+
5+
Initial release!

LICENCE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024, Michael Gendy
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include LICENSE
2+
include README.md
3+
recursive-include django_modal_actions/static *
4+
recursive-include django_modal_actions/templates *

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Django Modal Actions
2+
3+
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.
4+
5+
## Features
6+
7+
- Easy integration with Django admin
8+
- Support for both list-view and object-view actions
9+
- Customizable modal forms
10+
- AJAX-based form submission
11+
12+
## Requirements
13+
14+
- Python (>= 3.7)
15+
- Django (>= 3.2)
16+
17+
## Installation
18+
19+
1. Install the package using pip:
20+
21+
```
22+
pip install django-modal-actions
23+
```
24+
25+
2. Add `'django_modal_actions'` to your `INSTALLED_APPS` setting:
26+
27+
```python
28+
INSTALLED_APPS = [
29+
...
30+
'django_modal_actions',
31+
...
32+
]
33+
```
34+
35+
## Usage
36+
37+
1. In your `admin.py`, import the necessary components:
38+
39+
```python
40+
from django.contrib import admin
41+
from django_modal_actions import ModalActionMixin, modal_action
42+
```
43+
44+
2. Create a custom admin class that inherits from `ModalActionMixin` and your base admin class:
45+
46+
```python
47+
@admin.register(YourModel)
48+
class YourModelAdmin(ModalActionMixin, admin.ModelAdmin):
49+
modal_actions = ["your_object_action"]
50+
list_modal_actions = ["your_list_action"]
51+
52+
@modal_action(modal_header="Object Action")
53+
def your_object_action(self, request, obj, form_data=None):
54+
# Your object action logic here
55+
return "Action completed successfully"
56+
57+
@modal_action(modal_header="List Action")
58+
def your_list_action(self, request, queryset, form_data=None):
59+
# Your list action logic here
60+
return f"Action completed on {queryset.count()} items"
61+
```
62+
63+
3. If you need a custom form for your action, create a form class:
64+
65+
```python
66+
from django import forms
67+
68+
class CustomForm(forms.Form):
69+
name = forms.CharField(label="Name", required=True)
70+
71+
def clean_name(self):
72+
name = self.cleaned_data["name"]
73+
if name == "bad":
74+
raise forms.ValidationError("Name cannot be 'bad'")
75+
return name
76+
```
77+
78+
Then, use it in your action:
79+
80+
```python
81+
@modal_action(modal_header="Action with Form", form_class=CustomForm)
82+
def your_action_with_form(self, request, obj, form_data=None):
83+
# Your action logic here
84+
return f"Action completed with name: {form_data['name']}"
85+
```
86+
87+
## Testing
88+
89+
To run the tests, execute:
90+
91+
```
92+
python -m unittest discover django_modal_actions/tests
93+
```
94+
95+
## Contributing
96+
97+
Contributions are welcome! Please feel free to submit a Pull Request.
98+
99+
## License
100+
101+
This project is licensed under the MIT License.

django_modal_actions/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .mixins import ModalActionMixin, modal_action
2+
3+
__all__ = ["ModalActionMixin", "modal_action"]
4+
5+
6+
default_app_config = "django_modal_actions.apps.DjangoModalActionsConfig"

django_modal_actions/apps.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import os
2+
3+
from django.apps import AppConfig
4+
5+
6+
class DjangoModalActionsConfig(AppConfig):
7+
default_auto_field = "django.db.models.BigAutoField"
8+
name = "django_modal_actions"
9+
path = os.path.dirname(os.path.abspath(__file__))

0 commit comments

Comments
 (0)