Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Python & Django supported versions + migrate to ruff #551

Merged
merged 6 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
max-parallel: 5
matrix:
python-version: [3.6, 3.7, 3.8, 3.9, '3.10']
python-version: [3.8, 3.9, '3.10', 3.11, 3.12]
farridav marked this conversation as resolved.
Show resolved Hide resolved
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ admindocs_templates
*.sqlite3
tests/test_app/static/
.python-version
.mypy_cache
.ruff_cache
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ deps: ## Install dependencies
poetry install

lint: check-venv ## Lint the code
@printf "$(CYAN)Auto-formatting with black$(COFF)\n"
$(environment) black jazzmin tests
@printf "$(CYAN)Auto-formatting with ruff$(COFF)\n"
$(environment) ruff format jazzmin tests
$(environment) ruff check jazzmin tests --fix

check: check-venv ## Check code quality
@printf "$(CYAN)Running static code analysis$(COFF)\n"
$(environment) flake8
$(environment) black --check jazzmin tests
$(environment) ruff format --check jazzmin tests
$(environment) ruff check jazzmin tests
$(environment) mypy jazzmin tests --ignore-missing-imports

test: check-venv ## Run the test suite
Expand Down
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
# Django jazzmin (Jazzy Admin)

## Project Status

This project is being actively maintained, though with a reduced feature set, we are looking for contributors to help
maintain and improve the project, please get in touch if you would like to help.

Help needed with:

- Triaging issues
- Frontend fixes and UI improvements
- Testing
Expand All @@ -17,22 +19,24 @@ them as quickly as I would like, but im trying to get through them all now, hope
[![Docs](https://readthedocs.org/projects/django-jazzmin/badge/?version=latest)](https://django-jazzmin.readthedocs.io)
![PyPI download month](https://img.shields.io/pypi/dm/django-jazzmin.svg)
[![PyPI version](https://badge.fury.io/py/django-jazzmin.svg)](https://pypi.python.org/pypi/django-jazzmin/)
![Python versions](https://img.shields.io/badge/python-%3E%3D3.6-brightgreen)
![Django Versions](https://img.shields.io/badge/django-%3E%3D2-brightgreen)
![Python versions](https://img.shields.io/badge/python-%3E=3.8-brightgreen)
![Django Versions](https://img.shields.io/badge/django-%3E=4.2-brightgreen)
[![Coverage Status](https://coveralls.io/repos/github/farridav/django-jazzmin/badge.svg?branch=master)](https://coveralls.io/github/farridav/django-jazzmin?branch=master)

Drop-in theme for django admin, that utilises AdminLTE 3 & Bootstrap 4 to make yo' admin look jazzy

## Installation
```

```bash
pip install django-jazzmin
```

## Documentation
See [Documentation](https://django-jazzmin.readthedocs.io) or [Test App](https://github.com/farridav/django-jazzmin/tree/master/tests/test_app/library/settings.py)

See [Documentation](https://django-jazzmin.readthedocs.io) or [Test App](https://github.com/farridav/django-jazzmin/tree/master/tests/test_app/library/settings.py)

## Features

- Drop-in admin skin, all configuration optional
- Customisable side menu
- Customisable top menu
Expand All @@ -49,59 +53,75 @@ See [Documentation](https://django-jazzmin.readthedocs.io) or [Test App](https:/
## Screenshots

## Dashboard

![dashboard](https://django-jazzmin.readthedocs.io/img/dashboard.png)

## List view

![table list](https://django-jazzmin.readthedocs.io/img/list_view.png)

## Change form templates

### Collapsed side menu

![form page](https://django-jazzmin.readthedocs.io/img/detail_view.png)

### Expanded side menu

![Single](https://django-jazzmin.readthedocs.io/img/changeform_single.png)

### Horizontal tabs

![Horizontal tabs](https://django-jazzmin.readthedocs.io/img/changeform_horizontal_tabs.png)

### Vertical tabs

![Vertical tabs](https://django-jazzmin.readthedocs.io/img/changeform_vertical_tabs.png)

### Collapsible

![Collapsible](https://django-jazzmin.readthedocs.io/img/changeform_collapsible.png)

### Carousel

![Carousel](https://django-jazzmin.readthedocs.io/img/changeform_carousel.png)

### Related modal

![Related modal](https://django-jazzmin.readthedocs.io/img/related_modal_bootstrap.png)

## History page

![form page](https://django-jazzmin.readthedocs.io/img/history_page.png)

## Login view

![login](https://django-jazzmin.readthedocs.io/img/login.png)

## UI Customiser

![ui_customiser](https://django-jazzmin.readthedocs.io/img/ui_customiser.png)

## Mobile layout

![mobile](https://django-jazzmin.readthedocs.io/img/dashboard_mobile.png)

## Tablet layout

![tablet](https://django-jazzmin.readthedocs.io/img/dashboard_tablet.png)

## Admin Docs (if installed)

![admin_docs](https://django-jazzmin.readthedocs.io/img/admin_docs.png)

## Thanks
This was initially a Fork of https://github.com/wuyue92tree/django-adminlte-ui that we refactored so much we thought it

This was initially a Fork of <https://github.com/wuyue92tree/django-adminlte-ui> that we refactored so much we thought it
deserved its own package, big thanks to @wuyue92tree for all of his initial hard work, we are still patching into that
project were possible, but this project has taken a different direction.

The javascript modal implementation uses some code from [django-admin-interface](https://github.com/fabiocaccamo/django-admin-interface/blob/master/admin_interface/static/admin/js/popup_response.js), so thanks to @fabiocaccamo for original work

- Based on AdminLTE 3: https://adminlte.io/
- Using Bootstrap 4: https://getbootstrap.com/
- Using Font Awesome 5: https://fontawesome.com/
- Based on AdminLTE 3: <https://adminlte.io/>
- Using Bootstrap 4: <https://getbootstrap.com/>
- Using Font Awesome 5: <https://fontawesome.com/>
2 changes: 0 additions & 2 deletions docs/bugs_and_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ We welcome new features, here is a list of guidelines to consider:
5. Ensure that all configuration is optional
6. Ensure that any new strings are translated (but ideally try to use icons, or fallback on the comprehensive translations from Django)


When making changes, see if you can achieve your goal by removing code, failing that, try changing code, failing that, add new code

We prefer to use HTML first, failing that, use CSS, failing that, use JavaScript (This approach helps with maintainability)


Some useful links for feature development:

- [https://adminlte.io/themes/v3/index3.html](https://adminlte.io/themes/v3/index3.html)
Expand Down
65 changes: 41 additions & 24 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Configuration

To configure the general behaviour of jazzmin, you can use `JAZZMIN_SETTINGS` within your django settings, below is a
To configure the general behaviour of jazzmin, you can use `JAZZMIN_SETTINGS` within your django settings, below is a
full example, with some of the more complex items explained below that.

## Full example

```python
JAZZMIN_SETTINGS = {
# title of the window (Will default to current_admin_site.site_title if absent or None)
Expand Down Expand Up @@ -153,35 +154,36 @@ JAZZMIN_SETTINGS = {

You can enable the top menu by specifying `"topmenu_links"` in your `JAZZMIN_SETTINGS`, this is a list made up of one of:

- app (creates a dropdown of modeladmin links)
- model (creates a link to a modeladmin)
- url (url name, or absolute link)
- app (creates a dropdown of modeladmin links)
- model (creates a link to a modeladmin)
- url (url name, or absolute link)

The top menu can be styled with the UI Customiser (See below)

## User menu
You can add links to the user menu on the top right of the screen using the `"usermenu_links"` settings key, the format
of these links is the same as with top menu (above), though submenus via "app" are not currently supported and will not

You can add links to the user menu on the top right of the screen using the `"usermenu_links"` settings key, the format
of these links is the same as with top menu (above), though submenus via "app" are not currently supported and will not
be rendered.

![User Menu](./img/user_menu.png)

## Side menu

![Side Menu](./img/side_menu.png)

### How its generated

The side menu gets a list of all installed apps and their models that have admin classes, and creates a tree of apps and
The side menu gets a list of all installed apps and their models that have admin classes, and creates a tree of apps and
links to model admin pages.

You can omit apps, or models from this generated menu, using `hide_apps` or `hide_models` where app is like `auth` and
You can omit apps, or models from this generated menu, using `hide_apps` or `hide_models` where app is like `auth` and
model is like `auth.user`

Ordering of the menu can be done using `order_with_respect_to`, which is a list of apps/models/custom links you want to
Ordering of the menu can be done using `order_with_respect_to`, which is a list of apps/models/custom links you want to
base the ordering off of, it can be a full, or partial list, some examples:

```
```python
# Order the auth app before the books app, other apps will be alphabetically placed after these
"order_with_respect_to": ["auth", "books"],

Expand All @@ -208,9 +210,10 @@ Currently, custom links (See below) cannot be ordered

### Side menu custom links

Custom links can be added using `custom_links`, this is a dictionary of links, keyed on the app they will live under.
Custom links can be added using `custom_links`, this is a dictionary of links, keyed on the app they will live under.
Example:

```python
"custom_links": {
"books": [{
# Any Name you like
Expand All @@ -226,58 +229,69 @@ Example:
"permissions": ["books.view_book"]
}]
},
```

#### note

The app list you generate for the side menu, is shared with the dashboard, so any changes you make to it, will be reflected there

## Change form templates
We have a few different styles for a model admins change form controlled via the `changeform_format`, this can be applied
globally via `changeform_format`, and overriden on a per model basis using `changeform_format_overrides`, which accepts

We have a few different styles for a model admins change form controlled via the `changeform_format`, this can be applied
globally via `changeform_format`, and overriden on a per model basis using `changeform_format_overrides`, which accepts
a dictionary mapping of model names to changeform templates e.g:

```python
"changeform_format": "horizontal_tabs",
# override change forms on a per modeladmin basis
"changeform_format_overrides": {"auth.user": "collapsible", "auth.group": "vertical_tabs"},
```

Will use `horizontal_tabs` throughout the admin, but use the `collapsible` template on the user model admin, and
Will use `horizontal_tabs` throughout the admin, but use the `collapsible` template on the user model admin, and
`vertical_tabs` on the group model admin.

The default style is vertical tabs, *unless* you have no fieldsets and no inlines, in which case you will get the basic single form
rendered out, See [Django docs on fieldset](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets)
The default style is vertical tabs, *unless* you have no fieldsets and no inlines, in which case you will get the basic single form
rendered out, See [Django docs on fieldset](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets)
on how to add fieldsets to your admin classes.

See below for the different styles:

### Single page (`single`)

Render the form out in one page, including inlines, plain and simple, closest to the original Django admin change form

![Single](./img/changeform_single.png)

### Horizontal tabs (`horizontal_tabs`)
Puts all fieldsets and inlines into tab panes with horizontal nav tab controls, this is the default view for change

Puts all fieldsets and inlines into tab panes with horizontal nav tab controls, this is the default view for change
forms that have fieldsets. or an inline

![Horizontal tabs](./img/changeform_horizontal_tabs.png)

### Vertical tabs (`vertical_tabs`)

Puts each fieldset or inline in a separate pane, controlled by vertical tabs on the left hand side.

Future enhancement: Allow tabs to be on the left or right

![Vertical tabs](./img/changeform_vertical_tabs.png)

### Collapsible (`collapsible`)
Puts all fieldsets and inlines in bootstrap collapsibles in an collapsible, allows many collapsibles to be open at the

Puts all fieldsets and inlines in bootstrap collapsibles in an collapsible, allows many collapsibles to be open at the
same time, the first collapsible is opened

![Collapsible](./img/changeform_collapsible.png)

### Carousel (`carousel`)

Puts fieldsets and inlines into a bootstrap carousel, and allows paginaton with previous/next buttons, as well as an indicators.

![Carousel](./img/changeform_carousel.png)

## Ordering of page content

If you want to order the sections within your pages, you can specify `jazzmin_section_order` on your model admin class e.g:

```python
Expand All @@ -295,6 +309,7 @@ class BookAdmin(admin.ModelAdmin):
```

## Filter perfomance

If your filter will contain a lot of options, like when you use M2M filter or it's a big filter itself, then rendering every option can hurt user perfomance. This is solved by providing `filter_input_length` dictionary with filter name as the key and the value will determine how much characters should be entered before rendering options.

```python
Expand All @@ -314,7 +329,8 @@ class BookAdmin(admin.ModelAdmin):
```

## Language Chooser
You can enable a language chooser dropdown using `"language_chooser": True` in your `JAZZMIN_SETTINGS`, we mainly use this for

You can enable a language chooser dropdown using `"language_chooser": True` in your `JAZZMIN_SETTINGS`, we mainly use this for
assisting with translations, but it could be of use to some people in their admin site.

To make proper use of this, please ensure you have internationalisation setup properly, See [https://docs.djangoproject.com/en/3.1/topics/i18n/translation/](https://docs.djangoproject.com/en/3.1/topics/i18n/translation/)
Expand All @@ -326,20 +342,21 @@ Namely:
- `LOCALE_DIRS` is setup
- `LANGUAGES` have been defined

See our [test app settings](https://github.com/farridav/django-jazzmin/tree/master/tests/test_app/library/settings.py)
See our [test app settings](https://github.com/farridav/django-jazzmin/tree/master/tests/test_app/library/settings.py)
for a practical example.

![Language chooser](./img/language_chooser.png)

## Related Modal
Render django related popups inside a modal using `"related_modal_active": True` instead of the old popup window,

Render django related popups inside a modal using `"related_modal_active": True` instead of the old popup window,
defaults to `False`

![Related Modal](./img/related_modal_bootstrap.png)

### Adding extra actions to model's form view

Add a template for your model on your main template directory,
Add a template for your model on your main template directory,
e.g [app/templates/admin/app_name/model_name/submit_line.html](https://github.com/farridav/django-jazzmin/tree/master/tests/test_app/library/books/templates/admin/loans/bookloan/submit_line.html)

```djangotemplate
Expand Down Expand Up @@ -370,6 +387,6 @@ def response_change(self, request, obj):
pass
return ret
```

The implementation might change slightly if your wanting to perform an action on add, or delete, for those, you can
override the response_add of response_delete methods instead/as well.
Loading
Loading