django-bananas 2.2__tar.gz → 2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django-bananas-2.2 → django_bananas-2.4}/LICENSE +1 -1
- {django-bananas-2.2 → django_bananas-2.4}/MANIFEST.in +1 -1
- {django-bananas-2.2/src/django_bananas.egg-info → django_bananas-2.4}/PKG-INFO +36 -11
- {django-bananas-2.2 → django_bananas-2.4}/README.rst +7 -6
- django_bananas-2.4/pyproject.toml +97 -0
- django_bananas-2.4/setup.cfg +74 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/__init__.py +1 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/mixins.py +2 -2
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/schemas/base.py +1 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/schemas/yasg.py +2 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/v1_0/urls.py +2 -2
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/versioning.py +2 -3
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/views.py +6 -8
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/extension.py +23 -23
- {django-bananas-2.2/src/bananas/admin/api → django_bananas-2.4/src/bananas/admin}/i18n.py +0 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/drf/fencing.py +17 -14
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/drf/utils.py +4 -4
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/environment.py +32 -50
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/management/commands/show_urls.py +2 -2
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/management/commands/syncpermissions.py +0 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/models.py +6 -11
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/query.py +13 -10
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/secrets.py +4 -6
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/bananas/css/bananas.css +48 -28
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/bananas/css/banansive.css +17 -4
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/templates/admin/base_site.html +4 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/url.py +6 -7
- {django-bananas-2.2 → django_bananas-2.4/src/django_bananas.egg-info}/PKG-INFO +36 -11
- {django-bananas-2.2 → django_bananas-2.4}/src/django_bananas.egg-info/SOURCES.txt +1 -1
- {django-bananas-2.2 → django_bananas-2.4}/src/django_bananas.egg-info/requires.txt +5 -3
- django-bananas-2.2/pyproject.toml +0 -3
- django-bananas-2.2/setup.cfg +0 -132
- {django-bananas-2.2 → django_bananas-2.4}/AUTHORS +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/setup.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/permissions.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/router.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/schemas/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/schemas/decorators.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/serializers.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/urls.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/admin/api/v1_0/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/drf/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/drf/errors.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/lazy.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/management/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/management/commands/__init__.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/py.typed +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/settings.py +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/bananas/img/django.svg +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/bananas/img/search.svg +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/bananas/js/bananas.js +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/static/admin/css/responsive.css +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/bananas/templates/admin/view.html +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/django_bananas.egg-info/dependency_links.txt +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/django_bananas.egg-info/not-zip-safe +0 -0
- {django-bananas-2.2 → django_bananas-2.4}/src/django_bananas.egg-info/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
include setup.py README.rst MANIFEST.in LICENSE AUTHORS
|
|
2
|
-
exclude
|
|
2
|
+
exclude tox.ini *.yml *.yaml Makefile Dockerfile .editorconfig
|
|
3
3
|
|
|
4
4
|
recursive-include src/bananas/templates *
|
|
5
5
|
recursive-include src/bananas/static *
|
|
@@ -1,27 +1,51 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bananas
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4
|
|
4
4
|
Summary: Django Bananas - Django extensions the monkey way
|
|
5
5
|
Home-page: https://github.com/5monkeys/django-bananas
|
|
6
6
|
License: MIT License
|
|
7
7
|
Classifier: Development Status :: 5 - Production/Stable
|
|
8
8
|
Classifier: Programming Language :: Python
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
12
10
|
Classifier: Programming Language :: Python :: 3.8
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Framework :: Django
|
|
17
|
+
Classifier: Framework :: Django :: 3.2
|
|
18
|
+
Classifier: Framework :: Django :: 4.0
|
|
19
|
+
Classifier: Framework :: Django :: 4.1
|
|
20
|
+
Classifier: Framework :: Django :: 4.2
|
|
21
|
+
Classifier: Framework :: Django :: 5.0
|
|
22
|
+
Classifier: Framework :: Django :: 5.1
|
|
23
|
+
Classifier: Framework :: Django :: 5.2
|
|
15
24
|
Classifier: Intended Audience :: Developers
|
|
16
25
|
Classifier: License :: OSI Approved :: MIT License
|
|
17
26
|
Classifier: Operating System :: OS Independent
|
|
18
27
|
Classifier: Framework :: Django
|
|
19
28
|
Requires-Python: >=3.6
|
|
20
29
|
Description-Content-Type: text/x-rst; charset=UTF-8
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: Django>=2.2
|
|
32
|
+
Requires-Dist: typing-extensions>=3.7.4.3
|
|
21
33
|
Provides-Extra: drf
|
|
34
|
+
Requires-Dist: djangorestframework>=3.10; extra == "drf"
|
|
35
|
+
Requires-Dist: drf-yasg>=1.20.0; extra == "drf"
|
|
22
36
|
Provides-Extra: test
|
|
37
|
+
Requires-Dist: tox; extra == "test"
|
|
38
|
+
Requires-Dist: coverage[toml]; extra == "test"
|
|
23
39
|
Provides-Extra: dev
|
|
24
|
-
|
|
40
|
+
Requires-Dist: mypy; extra == "dev"
|
|
41
|
+
Requires-Dist: types-setuptools; extra == "dev"
|
|
42
|
+
Requires-Dist: django-stubs; extra == "dev"
|
|
43
|
+
Requires-Dist: djangorestframework-stubs; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest-django; extra == "dev"
|
|
47
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
48
|
+
Dynamic: license-file
|
|
25
49
|
|
|
26
50
|
================================================================================
|
|
27
51
|
:banana: Django Bananas - Django extensions the monkey way
|
|
@@ -57,10 +81,13 @@ with the ``drf`` extra to keep those in sync:
|
|
|
57
81
|
|
|
58
82
|
Currently tested only for
|
|
59
83
|
|
|
60
|
-
- Django 3.2 under Python 3.
|
|
84
|
+
- Django 3.2 under Python 3.8-3.10
|
|
61
85
|
- Django 4.0 under Python 3.8-3.10
|
|
62
|
-
- Django 4.1 under Python 3.8-3.
|
|
63
|
-
- Django 4.2 under Python 3.8-3.
|
|
86
|
+
- Django 4.1 under Python 3.8-3.13
|
|
87
|
+
- Django 4.2 under Python 3.8-3.13
|
|
88
|
+
- Django 5.0 under Python 3.10-3.13
|
|
89
|
+
- Django 5.1 under Python 3.10-3.13
|
|
90
|
+
- Django 5.2 under Python 3.10-3.13
|
|
64
91
|
|
|
65
92
|
Pull requests welcome!
|
|
66
93
|
|
|
@@ -263,7 +290,6 @@ feature requires installation with the ``drf`` extra.
|
|
|
263
290
|
|
|
264
291
|
|
|
265
292
|
class CustomAdminAPI(BananasAdminAPI):
|
|
266
|
-
|
|
267
293
|
name = lazy_title(_("custom"))
|
|
268
294
|
|
|
269
295
|
@schema(query_serializer=SomeSerializer, responses={200: SomeSerializer})
|
|
@@ -272,7 +298,6 @@ feature requires installation with the ``drf`` extra.
|
|
|
272
298
|
|
|
273
299
|
|
|
274
300
|
class SomeModelAdminAPI(BananasAPI, viewsets.ModelViewSet):
|
|
275
|
-
|
|
276
301
|
serializer_class = SomeModelSerializer
|
|
277
302
|
|
|
278
303
|
def list(self, request):
|
|
@@ -581,4 +606,4 @@ and select specific tests with the ``test`` argument to ``make test``:
|
|
|
581
606
|
|
|
582
607
|
.. code-block:: bash
|
|
583
608
|
|
|
584
|
-
make test test='
|
|
609
|
+
make test test='-k test_logout'
|
|
@@ -32,10 +32,13 @@ with the ``drf`` extra to keep those in sync:
|
|
|
32
32
|
|
|
33
33
|
Currently tested only for
|
|
34
34
|
|
|
35
|
-
- Django 3.2 under Python 3.
|
|
35
|
+
- Django 3.2 under Python 3.8-3.10
|
|
36
36
|
- Django 4.0 under Python 3.8-3.10
|
|
37
|
-
- Django 4.1 under Python 3.8-3.
|
|
38
|
-
- Django 4.2 under Python 3.8-3.
|
|
37
|
+
- Django 4.1 under Python 3.8-3.13
|
|
38
|
+
- Django 4.2 under Python 3.8-3.13
|
|
39
|
+
- Django 5.0 under Python 3.10-3.13
|
|
40
|
+
- Django 5.1 under Python 3.10-3.13
|
|
41
|
+
- Django 5.2 under Python 3.10-3.13
|
|
39
42
|
|
|
40
43
|
Pull requests welcome!
|
|
41
44
|
|
|
@@ -238,7 +241,6 @@ feature requires installation with the ``drf`` extra.
|
|
|
238
241
|
|
|
239
242
|
|
|
240
243
|
class CustomAdminAPI(BananasAdminAPI):
|
|
241
|
-
|
|
242
244
|
name = lazy_title(_("custom"))
|
|
243
245
|
|
|
244
246
|
@schema(query_serializer=SomeSerializer, responses={200: SomeSerializer})
|
|
@@ -247,7 +249,6 @@ feature requires installation with the ``drf`` extra.
|
|
|
247
249
|
|
|
248
250
|
|
|
249
251
|
class SomeModelAdminAPI(BananasAPI, viewsets.ModelViewSet):
|
|
250
|
-
|
|
251
252
|
serializer_class = SomeModelSerializer
|
|
252
253
|
|
|
253
254
|
def list(self, request):
|
|
@@ -556,4 +557,4 @@ and select specific tests with the ``test`` argument to ``make test``:
|
|
|
556
557
|
|
|
557
558
|
.. code-block:: bash
|
|
558
559
|
|
|
559
|
-
make test test='
|
|
560
|
+
make test test='-k test_logout'
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=57.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.black]
|
|
6
|
+
target-version = ["py38", "py39", "py310", "py311", "py312", "py313"]
|
|
7
|
+
|
|
8
|
+
[tool.ruff]
|
|
9
|
+
src = ["src"]
|
|
10
|
+
fix = true
|
|
11
|
+
target-version = "py38"
|
|
12
|
+
select = [
|
|
13
|
+
"B",
|
|
14
|
+
"C4",
|
|
15
|
+
"I",
|
|
16
|
+
"RUF",
|
|
17
|
+
"T20",
|
|
18
|
+
"TID",
|
|
19
|
+
"UP",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[tool.ruff.per-file-ignores]
|
|
23
|
+
"tests/**" = ["RUF012"]
|
|
24
|
+
|
|
25
|
+
[tool.ruff.isort]
|
|
26
|
+
known-first-party = ["src/"]
|
|
27
|
+
combine-as-imports = true
|
|
28
|
+
|
|
29
|
+
[tool.pytest.ini_options]
|
|
30
|
+
python_files = "tests.py test_*.py *_tests.py"
|
|
31
|
+
testpaths = ["tests"]
|
|
32
|
+
norecursedirs = "migrations"
|
|
33
|
+
|
|
34
|
+
[tool.coverage.paths]
|
|
35
|
+
source = [
|
|
36
|
+
"src/bananas",
|
|
37
|
+
"*/.tox/*/lib/*/site-packages/bananas"
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.coverage.run]
|
|
41
|
+
branch = true
|
|
42
|
+
source = ["src/", "tests/"]
|
|
43
|
+
|
|
44
|
+
[tool.coverage.report]
|
|
45
|
+
skip_covered = true
|
|
46
|
+
show_missing = true
|
|
47
|
+
fail_under= 94
|
|
48
|
+
exclude_lines = [
|
|
49
|
+
"pragma: no cover",
|
|
50
|
+
"if __name__ == .__main__.:",
|
|
51
|
+
# Ignore non-implementations
|
|
52
|
+
'^\s*\.\.\.',
|
|
53
|
+
"if TYPE_CHECKING:",
|
|
54
|
+
"raise NotImplementedError",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[tool.mypy]
|
|
58
|
+
python_version = "3.8"
|
|
59
|
+
show_error_codes = true
|
|
60
|
+
pretty = true
|
|
61
|
+
files = ["src", "tests", "setup.py"]
|
|
62
|
+
|
|
63
|
+
no_implicit_reexport = true
|
|
64
|
+
no_implicit_optional = true
|
|
65
|
+
strict_equality = true
|
|
66
|
+
strict_optional = true
|
|
67
|
+
check_untyped_defs = true
|
|
68
|
+
disallow_incomplete_defs = true
|
|
69
|
+
disallow_untyped_defs = true
|
|
70
|
+
ignore_missing_imports = false
|
|
71
|
+
|
|
72
|
+
warn_unused_configs = true
|
|
73
|
+
warn_redundant_casts = true
|
|
74
|
+
warn_unused_ignores = true
|
|
75
|
+
warn_return_any = true
|
|
76
|
+
warn_unreachable = true
|
|
77
|
+
|
|
78
|
+
plugins = [
|
|
79
|
+
"mypy_django_plugin.main",
|
|
80
|
+
"mypy_drf_plugin.main",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
[tool.django-stubs]
|
|
84
|
+
django_settings_module = "tests.conftest"
|
|
85
|
+
|
|
86
|
+
[[tool.mypy.overrides]]
|
|
87
|
+
module = [
|
|
88
|
+
"tests.*",
|
|
89
|
+
]
|
|
90
|
+
disallow_untyped_defs = false
|
|
91
|
+
|
|
92
|
+
[[tool.mypy.overrides]]
|
|
93
|
+
module = [
|
|
94
|
+
"test.support.*",
|
|
95
|
+
"drf_yasg.*",
|
|
96
|
+
]
|
|
97
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
name = django-bananas
|
|
3
|
+
description = Django Bananas - Django extensions the monkey way
|
|
4
|
+
long_description = file: README.rst
|
|
5
|
+
long_description_content_type = text/x-rst; charset=UTF-8
|
|
6
|
+
url = https://github.com/5monkeys/django-bananas
|
|
7
|
+
version = attr: bananas.__version__
|
|
8
|
+
classifiers =
|
|
9
|
+
Development Status :: 5 - Production/Stable
|
|
10
|
+
Programming Language :: Python
|
|
11
|
+
Programming Language :: Python :: 3
|
|
12
|
+
Programming Language :: Python :: 3.8
|
|
13
|
+
Programming Language :: Python :: 3.9
|
|
14
|
+
Programming Language :: Python :: 3.10
|
|
15
|
+
Programming Language :: Python :: 3.11
|
|
16
|
+
Programming Language :: Python :: 3.12
|
|
17
|
+
Programming Language :: Python :: 3.13
|
|
18
|
+
Framework :: Django
|
|
19
|
+
Framework :: Django :: 3.2
|
|
20
|
+
Framework :: Django :: 4.0
|
|
21
|
+
Framework :: Django :: 4.1
|
|
22
|
+
Framework :: Django :: 4.2
|
|
23
|
+
Framework :: Django :: 5.0
|
|
24
|
+
Framework :: Django :: 5.1
|
|
25
|
+
Framework :: Django :: 5.2
|
|
26
|
+
Intended Audience :: Developers
|
|
27
|
+
License :: OSI Approved :: MIT License
|
|
28
|
+
Operating System :: OS Independent
|
|
29
|
+
Framework :: Django
|
|
30
|
+
license = MIT License
|
|
31
|
+
license_file = LICENSE
|
|
32
|
+
|
|
33
|
+
[options]
|
|
34
|
+
packages = find:
|
|
35
|
+
package_dir =
|
|
36
|
+
=src
|
|
37
|
+
python_requires = >=3.6
|
|
38
|
+
include_package_data = True
|
|
39
|
+
exclude =
|
|
40
|
+
tests
|
|
41
|
+
_*
|
|
42
|
+
example
|
|
43
|
+
zip_safe = False
|
|
44
|
+
install_requires =
|
|
45
|
+
Django>=2.2
|
|
46
|
+
typing-extensions>=3.7.4.3
|
|
47
|
+
|
|
48
|
+
[options.packages.find]
|
|
49
|
+
where = src
|
|
50
|
+
|
|
51
|
+
[options.extras_require]
|
|
52
|
+
drf =
|
|
53
|
+
djangorestframework>=3.10
|
|
54
|
+
drf-yasg>=1.20.0
|
|
55
|
+
test =
|
|
56
|
+
tox
|
|
57
|
+
coverage[toml]
|
|
58
|
+
dev =
|
|
59
|
+
mypy
|
|
60
|
+
types-setuptools
|
|
61
|
+
django-stubs
|
|
62
|
+
djangorestframework-stubs
|
|
63
|
+
pytest
|
|
64
|
+
pytest-cov
|
|
65
|
+
pytest-django
|
|
66
|
+
pre-commit
|
|
67
|
+
|
|
68
|
+
[options.package_data]
|
|
69
|
+
bananas = py.typed
|
|
70
|
+
|
|
71
|
+
[egg_info]
|
|
72
|
+
tag_build =
|
|
73
|
+
tag_date = 0
|
|
74
|
+
|
|
@@ -63,9 +63,9 @@ class BananasAPI:
|
|
|
63
63
|
if admin is not None:
|
|
64
64
|
meta.update(
|
|
65
65
|
{
|
|
66
|
-
key: getattr(admin, key)
|
|
66
|
+
key: getattr(admin, key)
|
|
67
67
|
for key in filter(
|
|
68
|
-
lambda key: key in meta,
|
|
68
|
+
lambda key: key in meta,
|
|
69
69
|
admin.__dict__.keys(),
|
|
70
70
|
)
|
|
71
71
|
}
|
|
@@ -13,7 +13,8 @@ from rest_framework.request import Request
|
|
|
13
13
|
from rest_framework.routers import SimpleRouter
|
|
14
14
|
from rest_framework.schemas.coreapi import is_custom_action
|
|
15
15
|
|
|
16
|
-
from
|
|
16
|
+
from bananas.admin.api.versioning import BananasVersioning
|
|
17
|
+
|
|
17
18
|
from .base import BananasBaseRouter
|
|
18
19
|
|
|
19
20
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from types import ModuleType
|
|
2
|
-
from typing import Dict, Sequence
|
|
2
|
+
from typing import ClassVar, Dict, Sequence
|
|
3
3
|
|
|
4
4
|
from rest_framework.request import Request
|
|
5
5
|
from rest_framework.versioning import NamespaceVersioning
|
|
@@ -10,12 +10,11 @@ __versions__ = [v1_0]
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class BananasVersioning(NamespaceVersioning):
|
|
13
|
-
|
|
14
13
|
default_version: str = v1_0.__version__
|
|
15
14
|
allowed_versions: Sequence[str] = tuple(
|
|
16
15
|
version.__version__ for version in __versions__
|
|
17
16
|
)
|
|
18
|
-
version_map: Dict[str, ModuleType] = {
|
|
17
|
+
version_map: ClassVar[Dict[str, ModuleType]] = {
|
|
19
18
|
version.__version__: version for version in __versions__
|
|
20
19
|
}
|
|
21
20
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import ClassVar, List
|
|
2
|
+
|
|
1
3
|
from django.contrib.auth import (
|
|
2
4
|
login as auth_login,
|
|
3
5
|
logout as auth_logout,
|
|
@@ -11,7 +13,8 @@ from rest_framework.permissions import AllowAny
|
|
|
11
13
|
from rest_framework.request import Request
|
|
12
14
|
from rest_framework.response import Response
|
|
13
15
|
|
|
14
|
-
from .i18n import RawTranslationCatalog
|
|
16
|
+
from bananas.admin.i18n import RawTranslationCatalog
|
|
17
|
+
|
|
15
18
|
from .mixins import BananasAPI
|
|
16
19
|
from .permissions import IsAnonymous
|
|
17
20
|
from .schemas import schema
|
|
@@ -29,7 +32,6 @@ class BananasAdminAPI(BananasAPI, viewsets.GenericViewSet):
|
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
class LoginAPI(BananasAdminAPI):
|
|
32
|
-
|
|
33
35
|
name = _("Log in") # type: ignore[assignment]
|
|
34
36
|
basename = "login"
|
|
35
37
|
permission_classes = (IsAnonymous,)
|
|
@@ -60,7 +62,6 @@ class LoginAPI(BananasAdminAPI):
|
|
|
60
62
|
|
|
61
63
|
|
|
62
64
|
class LogoutAPI(BananasAPI, viewsets.ViewSet):
|
|
63
|
-
|
|
64
65
|
name = _("Log out") # type: ignore[assignment]
|
|
65
66
|
basename = "logout"
|
|
66
67
|
|
|
@@ -77,11 +78,10 @@ class LogoutAPI(BananasAPI, viewsets.ViewSet):
|
|
|
77
78
|
|
|
78
79
|
|
|
79
80
|
class MeAPI(BananasAdminAPI):
|
|
80
|
-
|
|
81
81
|
serializer_class = UserSerializer
|
|
82
82
|
|
|
83
83
|
class Admin:
|
|
84
|
-
exclude_tags = ["navigation"]
|
|
84
|
+
exclude_tags: ClassVar[List[str]] = ["navigation"]
|
|
85
85
|
|
|
86
86
|
@schema(responses={200: UserSerializer})
|
|
87
87
|
def list(self, request: Request) -> Response:
|
|
@@ -93,7 +93,6 @@ class MeAPI(BananasAdminAPI):
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
class ChangePasswordAPI(BananasAdminAPI):
|
|
96
|
-
|
|
97
96
|
name = _("Change password") # type: ignore[assignment]
|
|
98
97
|
basename = "change_password"
|
|
99
98
|
serializer_class = PasswordChangeSerializer # Placeholder for schema
|
|
@@ -121,13 +120,12 @@ class ChangePasswordAPI(BananasAdminAPI):
|
|
|
121
120
|
|
|
122
121
|
|
|
123
122
|
class TranslationAPI(BananasAdminAPI):
|
|
124
|
-
|
|
125
123
|
name = _("Translation catalog") # type: ignore[assignment]
|
|
126
124
|
basename = "i18n"
|
|
127
125
|
permission_classes = (AllowAny,)
|
|
128
126
|
|
|
129
127
|
class Admin:
|
|
130
|
-
exclude_tags = ["navigation"]
|
|
128
|
+
exclude_tags: ClassVar[List[str]] = ["navigation"]
|
|
131
129
|
|
|
132
130
|
@schema(responses={200: ""})
|
|
133
131
|
def list(self, request: Request) -> Response:
|
|
@@ -2,6 +2,7 @@ import re
|
|
|
2
2
|
from typing import (
|
|
3
3
|
Any,
|
|
4
4
|
Callable,
|
|
5
|
+
ClassVar,
|
|
5
6
|
Dict,
|
|
6
7
|
List,
|
|
7
8
|
Optional,
|
|
@@ -31,7 +32,7 @@ from django.utils.safestring import SafeText, mark_safe
|
|
|
31
32
|
from django.utils.translation import gettext_lazy as _
|
|
32
33
|
from django.views.generic import View
|
|
33
34
|
|
|
34
|
-
from
|
|
35
|
+
from bananas.environment import env
|
|
35
36
|
|
|
36
37
|
__all__ = ["ModelAdminView", "ViewTool", "AdminView", "register", "site"]
|
|
37
38
|
|
|
@@ -41,7 +42,7 @@ MT = TypeVar("MT", bound=Model)
|
|
|
41
42
|
|
|
42
43
|
class ExtendedAdminSite(AdminSite):
|
|
43
44
|
enable_nav_sidebar = False
|
|
44
|
-
default_settings = {
|
|
45
|
+
default_settings: ClassVar[Dict[str, Any]] = {
|
|
45
46
|
"INHERIT_REGISTERED_MODELS": env.get_bool(
|
|
46
47
|
"DJANGO_ADMIN_INHERIT_REGISTERED_MODELS", True
|
|
47
48
|
),
|
|
@@ -84,10 +85,8 @@ class ModelAdminView(ModelAdmin):
|
|
|
84
85
|
@cached_property
|
|
85
86
|
def access_permission(self) -> str:
|
|
86
87
|
meta = self.model._meta
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
codename=meta.permissions[0][0], # First perm codename
|
|
90
|
-
)
|
|
88
|
+
codename = meta.permissions[0][0] # First perm codename
|
|
89
|
+
return f"{meta.app_label}.{codename}"
|
|
91
90
|
|
|
92
91
|
def get_urls(self) -> List[URLPattern]:
|
|
93
92
|
app_label = self.model._meta.app_label
|
|
@@ -122,7 +121,8 @@ class ModelAdminView(ModelAdmin):
|
|
|
122
121
|
|
|
123
122
|
admin_login_url = reverse_lazy("admin:login")
|
|
124
123
|
view = user_passes_test(
|
|
125
|
-
lambda u: u.is_active and hasattr(u, "is_staff") and u.is_staff,
|
|
124
|
+
lambda u: u.is_active and hasattr(u, "is_staff") and u.is_staff,
|
|
125
|
+
login_url=admin_login_url,
|
|
126
126
|
)(view)
|
|
127
127
|
view = permission_required(perm, login_url=admin_login_url)(view)
|
|
128
128
|
return view
|
|
@@ -133,12 +133,12 @@ class ModelAdminView(ModelAdmin):
|
|
|
133
133
|
return perm
|
|
134
134
|
|
|
135
135
|
def has_module_permission(self, request: HttpRequest) -> bool:
|
|
136
|
-
return request.user.has_perm(self.access_permission)
|
|
136
|
+
return bool(request.user.has_perm(self.access_permission))
|
|
137
137
|
|
|
138
138
|
def has_change_permission(
|
|
139
139
|
self, request: HttpRequest, obj: Optional[MT] = None
|
|
140
140
|
) -> bool:
|
|
141
|
-
return request.user.has_perm(self.access_permission)
|
|
141
|
+
return bool(request.user.has_perm(self.access_permission))
|
|
142
142
|
|
|
143
143
|
# TODO: Remove obj?
|
|
144
144
|
def has_add_permission(
|
|
@@ -175,8 +175,7 @@ def register(
|
|
|
175
175
|
*,
|
|
176
176
|
admin_site: Optional[AdminSite] = None,
|
|
177
177
|
admin_class: Type[ModelAdmin] = ModelAdminView,
|
|
178
|
-
) -> Type["AdminView"]:
|
|
179
|
-
...
|
|
178
|
+
) -> Type["AdminView"]: ...
|
|
180
179
|
|
|
181
180
|
|
|
182
181
|
# Call with parenthesis: @register()
|
|
@@ -186,8 +185,7 @@ def register(
|
|
|
186
185
|
*,
|
|
187
186
|
admin_site: Optional[AdminSite] = None,
|
|
188
187
|
admin_class: Type[ModelAdmin] = ModelAdminView,
|
|
189
|
-
) -> Callable[[Type["AdminView"]], Type["AdminView"]]:
|
|
190
|
-
...
|
|
188
|
+
) -> Callable[[Type["AdminView"]], Type["AdminView"]]: ...
|
|
191
189
|
|
|
192
190
|
|
|
193
191
|
def register(
|
|
@@ -236,14 +234,14 @@ def register(
|
|
|
236
234
|
inner_view.verbose_name = verbose_name
|
|
237
235
|
|
|
238
236
|
access_perm_codename = "can_access_" + model_name.lower()
|
|
239
|
-
access_perm_name = _("Can access {verbose_name}").format(
|
|
237
|
+
access_perm_name = str(_("Can access {verbose_name}")).format(
|
|
240
238
|
verbose_name=verbose_name
|
|
241
239
|
)
|
|
242
240
|
# The first permission here is expected to be
|
|
243
241
|
# the general access permission.
|
|
244
|
-
permissions =
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
permissions = (
|
|
243
|
+
(access_perm_codename, access_perm_name),
|
|
244
|
+
*list(getattr(inner_view, "permissions", [])),
|
|
247
245
|
)
|
|
248
246
|
|
|
249
247
|
model = type(
|
|
@@ -303,9 +301,11 @@ class ViewTool:
|
|
|
303
301
|
|
|
304
302
|
|
|
305
303
|
class AdminView(View):
|
|
306
|
-
tools:
|
|
307
|
-
|
|
308
|
-
|
|
304
|
+
tools: ClassVar[
|
|
305
|
+
Optional[List[Union[Tuple[str, str], Tuple[str, str, str], ViewTool]]]
|
|
306
|
+
] = None
|
|
307
|
+
action: ClassVar[Optional[str]] = None
|
|
308
|
+
admin: ClassVar[Optional[ModelAdminView]] = None
|
|
309
309
|
|
|
310
310
|
label: str
|
|
311
311
|
verbose_name: str
|
|
@@ -354,8 +354,8 @@ class AdminView(View):
|
|
|
354
354
|
# Mypy doesn't change type on a len(...) call
|
|
355
355
|
# See: https://github.com/python/mypy/issues/1178
|
|
356
356
|
if len(tool) == 3:
|
|
357
|
-
tool, perm =
|
|
358
|
-
text, link =
|
|
357
|
+
tool, perm = tool[:-1], tool[-1]
|
|
358
|
+
text, link = tool
|
|
359
359
|
tool = ViewTool(text, link, perm=perm)
|
|
360
360
|
else:
|
|
361
361
|
# Assume ViewTool
|
|
@@ -385,7 +385,7 @@ class AdminView(View):
|
|
|
385
385
|
|
|
386
386
|
def has_permission(self, perm: str) -> bool:
|
|
387
387
|
perm = self.get_permission(perm)
|
|
388
|
-
return self.request.user.has_perm(perm)
|
|
388
|
+
return bool(self.request.user.has_perm(perm))
|
|
389
389
|
|
|
390
390
|
def has_access(self) -> bool:
|
|
391
391
|
assert self.admin is not None
|