django-api-admin 1.2.2__tar.gz → 1.2.3__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.
Files changed (103) hide show
  1. django_api_admin-1.2.3/LICENSE-DJANGO +27 -0
  2. django_api_admin-1.2.3/LICENSE-RESTFUL-ADMIN +21 -0
  3. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/PKG-INFO +14 -33
  4. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/README.md +2 -3
  5. django_api_admin-1.2.3/assets/images/logo.png +0 -0
  6. django_api_admin-1.2.3/assets/images/screenshot.png +0 -0
  7. django_api_admin-1.2.3/django_api_admin/admin_views/admin_site_views/admin_api_root.py +51 -0
  8. django_api_admin-1.2.2/django_api_admin/admin_views/admin_site_views/index.py → django_api_admin-1.2.3/django_api_admin/admin_views/admin_site_views/app_list.py +2 -4
  9. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/autocomplete.py +12 -1
  10. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/language_catalog.py +2 -2
  11. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/site_context.py +0 -2
  12. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/add.py +21 -19
  13. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/change.py +7 -3
  14. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/detail.py +3 -3
  15. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/history.py +1 -2
  16. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/list.py +0 -4
  17. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admins/base_admin.py +23 -12
  18. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admins/inline_admin.py +22 -13
  19. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admins/model_admin.py +39 -28
  20. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/changelist.py +12 -0
  21. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/checks.py +13 -1
  22. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/decorators.py +14 -0
  23. django_api_admin-1.2.3/django_api_admin/exceptions.py +49 -0
  24. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/filters.py +8 -1
  25. django_api_admin-1.2.3/django_api_admin/hooks.py +99 -0
  26. django_api_admin-1.2.3/django_api_admin/locale/ar/LC_MESSAGES/django.po +671 -0
  27. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/models.py +12 -0
  28. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/openapi.py +22 -0
  29. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/serializers.py +8 -0
  30. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/sites.py +104 -75
  31. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/_get_non_gfk_field.py +7 -0
  32. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/diff_helper.py +6 -0
  33. django_api_admin-1.2.3/django_api_admin/utils/flatten.py +18 -0
  34. django_api_admin-1.2.3/django_api_admin/utils/get_content_type_for_model.py +13 -0
  35. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_deleted_objects.py +7 -0
  36. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_field_attributes.py +0 -1
  37. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_fields_from_path.py +7 -0
  38. django_api_admin-1.2.3/django_api_admin/utils/get_form_config.py +8 -0
  39. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_form_fields.py +10 -9
  40. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_inline_by_field_name.py +1 -4
  41. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_inlines.py +10 -7
  42. django_api_admin-1.2.3/django_api_admin/utils/get_model_from_relation.py +15 -0
  43. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/get_related_name.py +1 -4
  44. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/label_for_field.py +7 -0
  45. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/lookup_field.py +7 -0
  46. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/lookup_spawns_duplicates.py +7 -0
  47. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/model_format_dict.py +7 -0
  48. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/model_ngettext.py +7 -0
  49. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/nested_objects.py +7 -0
  50. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/prepare_lookup_value.py +7 -0
  51. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/quote.py +7 -0
  52. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/reverse_field_path.py +7 -0
  53. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/url_params_from_lookup_dict.py +7 -0
  54. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/validate_bulk_edits.py +51 -47
  55. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/validate_inline_field_names.py +5 -5
  56. django_api_admin-1.2.3/pyproject.toml +47 -0
  57. django_api_admin-1.2.2/django_api_admin/admin_views/admin_site_views/admin_api_root.py +0 -23
  58. django_api_admin-1.2.2/django_api_admin/exceptions.py +0 -31
  59. django_api_admin-1.2.2/django_api_admin/hooks.py +0 -67
  60. django_api_admin-1.2.2/django_api_admin/utils/flatten.py +0 -11
  61. django_api_admin-1.2.2/django_api_admin/utils/get_content_type_for_model.py +0 -6
  62. django_api_admin-1.2.2/django_api_admin/utils/get_form_config.py +0 -13
  63. django_api_admin-1.2.2/django_api_admin/utils/get_model_from_relation.py +0 -8
  64. django_api_admin-1.2.2/django_api_admin.egg-info/PKG-INFO +0 -383
  65. django_api_admin-1.2.2/django_api_admin.egg-info/SOURCES.txt +0 -88
  66. django_api_admin-1.2.2/django_api_admin.egg-info/dependency_links.txt +0 -1
  67. django_api_admin-1.2.2/django_api_admin.egg-info/requires.txt +0 -7
  68. django_api_admin-1.2.2/django_api_admin.egg-info/top_level.txt +0 -2
  69. django_api_admin-1.2.2/pyproject.toml +0 -44
  70. django_api_admin-1.2.2/setup.cfg +0 -4
  71. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/LICENSE +0 -0
  72. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/__init__.py +0 -0
  73. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/actions.py +0 -0
  74. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/__init__.py +0 -0
  75. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/admin_log.py +0 -0
  76. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/app_index.py +0 -0
  77. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/obtain_token.py +0 -0
  78. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/password_change.py +0 -0
  79. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/token_refresh.py +0 -0
  80. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/user_information.py +0 -0
  81. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/admin_site_views/view_on_site.py +0 -0
  82. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/__init__.py +0 -0
  83. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/changelist.py +0 -0
  84. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/delete.py +1 -1
  85. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admin_views/model_admin_views/handle_action.py +0 -0
  86. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/admins/__init__.py +0 -0
  87. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/apps.py +0 -0
  88. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/constants/__init__.py +0 -0
  89. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/constants/field_attributes.py +0 -0
  90. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/constants/vars.py +0 -0
  91. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/declarations/__init__.py +0 -0
  92. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/declarations/functions.py +0 -0
  93. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/migrations/0001_initial.py +0 -0
  94. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/migrations/__init__.py +0 -0
  95. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/options.py +0 -0
  96. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/pagination.py +0 -0
  97. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/permissions.py +0 -0
  98. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/__init__.py +0 -0
  99. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/force_login.py +0 -0
  100. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/utils/remove_field.py +0 -0
  101. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/views/__init__.py +0 -0
  102. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/views/admin_views.py +0 -0
  103. {django_api_admin-1.2.2 → django_api_admin-1.2.3}/django_api_admin/views/site_views.py +0 -0
@@ -0,0 +1,27 @@
1
+ Copyright (c) Django Software Foundation and individual contributors.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of Django nor the names of its contributors may be used
15
+ to endorse or promote products derived from this software without
16
+ specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 amirasaran
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.
@@ -1,42 +1,24 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: django-api-admin
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: A RESTful API implementation of django.contrib.admin, designed for writing custom frontends.
5
+ Author: Muhammad Salah
5
6
  Author-email: Muhammad Salah <msbizzacc0unt@outlook.com>
6
- License: MIT License
7
-
8
- Copyright (c) 2021 Muhammad Salah
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
- Project-URL: Github, https://github.com/demon-bixia/django-api-admin
7
+ License-File: LICENSE
8
+ License-File: LICENSE-DJANGO
9
+ License-File: LICENSE-RESTFUL-ADMIN
29
10
  Classifier: Programming Language :: Python :: 3
30
11
  Classifier: License :: OSI Approved :: MIT License
31
12
  Classifier: Operating System :: OS Independent
32
- Description-Content-Type: text/markdown
33
- License-File: LICENSE
34
13
  Requires-Dist: django
35
14
  Requires-Dist: djangorestframework
36
- Requires-Dist: djangorestframework-simplejwt
37
15
  Requires-Dist: drf-spectacular
38
- Provides-Extra: dev
39
- Requires-Dist: django-cors-headers; extra == "dev"
16
+ Requires-Dist: djangorestframework-simplejwt
17
+ Requires-Dist: django-cors-headers ; extra == 'example'
18
+ Requires-Dist: python-dotenv>=1.1.1 ; extra == 'example'
19
+ Project-URL: Github, https://github.com/demon-bixia/django-api-admin
20
+ Provides-Extra: example
21
+ Description-Content-Type: text/markdown
40
22
 
41
23
  <a id="readme-top"></a>
42
24
 
@@ -108,7 +90,7 @@ Requires-Dist: django-cors-headers; extra == "dev"
108
90
  <!-- ABOUT THE PROJECT -->
109
91
  ## About The Project
110
92
 
111
- [![Product Name Screen Shot][product-screenshot]](https://example.com)
93
+ [![Product Name Screen Shot][product-screenshot]](https://github.com/demon-bixia/django-api-admin)
112
94
 
113
95
  The Django API Admin project is a RESTful API implementation of the `django.contrib.admin` module, designed to facilitate the creation of custom frontends. This project aims to provide developers with a robust and flexible API that mirrors the functionality of Django's built-in admin interface, allowing for seamless integration with modern web applications.
114
96
 
@@ -284,7 +266,7 @@ This section provides a simple example on how to use django-api-admin. If you're
284
266
  - [ ] Oauth support
285
267
  - [ ] Multi-language Support
286
268
  - [ ] Arabic
287
- - [ ] Spanish
269
+ - [x] English
288
270
 
289
271
  See the [open issues](https://github.com/demon-bixia/django-api-admin/issues) for a full list of proposed features (and known issues).
290
272
 
@@ -348,7 +330,6 @@ This section is dedicated to recognizing the valuable resources and contribution
348
330
  * [DRF Spectacular](https://github.com/tfranzel/drf-spectacular)
349
331
  * [Django Restful Admin](https://github.com/amirasaran/django-restful-admin)
350
332
  * [Best README Template](https://github.com/othneildrew/Best-README-Template)
351
- * [QODO AI](https://www.qodo.ai/)
352
333
 
353
334
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
354
335
 
@@ -68,7 +68,7 @@
68
68
  <!-- ABOUT THE PROJECT -->
69
69
  ## About The Project
70
70
 
71
- [![Product Name Screen Shot][product-screenshot]](https://example.com)
71
+ [![Product Name Screen Shot][product-screenshot]](https://github.com/demon-bixia/django-api-admin)
72
72
 
73
73
  The Django API Admin project is a RESTful API implementation of the `django.contrib.admin` module, designed to facilitate the creation of custom frontends. This project aims to provide developers with a robust and flexible API that mirrors the functionality of Django's built-in admin interface, allowing for seamless integration with modern web applications.
74
74
 
@@ -244,7 +244,7 @@ This section provides a simple example on how to use django-api-admin. If you're
244
244
  - [ ] Oauth support
245
245
  - [ ] Multi-language Support
246
246
  - [ ] Arabic
247
- - [ ] Spanish
247
+ - [x] English
248
248
 
249
249
  See the [open issues](https://github.com/demon-bixia/django-api-admin/issues) for a full list of proposed features (and known issues).
250
250
 
@@ -308,7 +308,6 @@ This section is dedicated to recognizing the valuable resources and contribution
308
308
  * [DRF Spectacular](https://github.com/tfranzel/drf-spectacular)
309
309
  * [Django Restful Admin](https://github.com/amirasaran/django-restful-admin)
310
310
  * [Best README Template](https://github.com/othneildrew/Best-README-Template)
311
- * [QODO AI](https://www.qodo.ai/)
312
311
 
313
312
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
314
313
 
@@ -0,0 +1,51 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+
3
+ from rest_framework import status
4
+ from rest_framework.response import Response
5
+ from rest_framework.views import APIView
6
+ from rest_framework.reverse import reverse
7
+
8
+ from drf_spectacular.utils import extend_schema, OpenApiResponse
9
+
10
+ from django_api_admin.openapi import CommonAPIResponses, APIResponseExamples
11
+ from django_api_admin.serializers import APIRootSerializer
12
+
13
+
14
+ class AdminAPIRootView(APIView):
15
+ """
16
+ A list of urls that act as a starting point for browsing the REST API
17
+ """
18
+ root_urls = None
19
+ admin_site = None
20
+
21
+ @extend_schema(
22
+ responses={
23
+ 200: OpenApiResponse(
24
+ description=_(
25
+ "A list of urls that act as a starting point for browsing the REST API"),
26
+ response=APIRootSerializer,
27
+ examples=[APIResponseExamples.root_urls()]
28
+ ),
29
+ 401: CommonAPIResponses.unauthorized()
30
+ }
31
+ )
32
+ def get(self, request, ):
33
+ namespace = request.resolver_match.namespace
34
+ data = dict()
35
+
36
+ for url in self.root_urls:
37
+ # Include the app_index url for every app
38
+ if url.name == 'app_index':
39
+ valid_app_labels = set(model._meta.app_label for model,
40
+ _ in self.admin_site._registry.items())
41
+ for app_label in valid_app_labels:
42
+ data[f'{app_label}_{url.name}'] = reverse(
43
+ f'{namespace}:{url.name}', kwargs={"app_label": app_label}, request=request)
44
+
45
+ # Include the rest of the urls except the view_on_site
46
+ # todo: consider including the view_on_site url index every object's detail view response
47
+ elif url.name != "view_on_site":
48
+ data[url.name] = reverse(
49
+ f'{namespace}:{url.name}', request=request)
50
+
51
+ return Response(data or {}, status=status.HTTP_200_OK)
@@ -1,5 +1,3 @@
1
- # from django.utils.translation import gettext_lazy as _
2
-
3
1
  from rest_framework import status
4
2
  from rest_framework.response import Response
5
3
  from rest_framework.reverse import reverse
@@ -11,7 +9,7 @@ from django_api_admin.serializers import AppListSerializer
11
9
  from django_api_admin.openapi import CommonAPIResponses
12
10
 
13
11
 
14
- class IndexView(APIView):
12
+ class AppListView(APIView):
15
13
  """
16
14
  Return json object that lists all the installed
17
15
  apps that have been registered by the admin site.
@@ -31,7 +29,7 @@ class IndexView(APIView):
31
29
  app_list = self.admin_site.get_app_list(request)
32
30
  # add an url to app_index in every app in app_list
33
31
  for app in app_list:
34
- app['url'] = reverse(f'{self.admin_site.name}:app_list', kwargs={
32
+ app['url'] = reverse(f'{self.admin_site.name}:app_index', kwargs={
35
33
  'app_label': app['app_label']}, request=request)
36
34
  data = {'app_list': app_list}
37
35
  request.current_app = self.admin_site.name
@@ -1,3 +1,15 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Portions of this file are from Django (https://www.djangoproject.com/)
3
+ # Copyright (c) Django Software Foundation and individual contributors.
4
+ # All rights reserved.
5
+ # Licensed under the BSD 3-Clause License.
6
+ #
7
+ # Additional code copyright (c) 2021 Muhammad Salah
8
+ # Licensed under the MIT License
9
+ #
10
+ # This file includes both Django code and your my own contributions.
11
+ # -----------------------------------------------------------------------------
12
+
1
13
  from django.apps import apps
2
14
  from django.utils.translation import gettext_lazy as _
3
15
  from django.core.exceptions import FieldDoesNotExist
@@ -6,7 +18,6 @@ from rest_framework.exceptions import PermissionDenied, ParseError
6
18
  from rest_framework.views import APIView
7
19
  from rest_framework.response import Response
8
20
  from rest_framework import status
9
- from rest_framework.views import APIView
10
21
 
11
22
  from drf_spectacular.utils import extend_schema, OpenApiExample, OpenApiResponse
12
23
 
@@ -1,9 +1,9 @@
1
-
2
- from django.utils.translation import gettext_lazy as _
3
1
  import json
4
2
 
3
+ from django.utils.translation import gettext_lazy as _
5
4
  from django.views.i18n import JSONCatalog
6
5
 
6
+ from rest_framework import status
7
7
  from rest_framework.response import Response
8
8
  from rest_framework.views import APIView
9
9
 
@@ -1,5 +1,3 @@
1
- # from django.utils.translation import gettext_lazy as _
2
-
3
1
  from rest_framework import status
4
2
  from rest_framework.response import Response
5
3
  from rest_framework.views import APIView
@@ -6,7 +6,7 @@ from rest_framework.response import Response
6
6
  from rest_framework.exceptions import PermissionDenied
7
7
  from rest_framework.views import APIView
8
8
 
9
- from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample
9
+ from drf_spectacular.utils import extend_schema, OpenApiResponse
10
10
 
11
11
  from django_api_admin.utils.get_form_fields import get_form_fields
12
12
  from django_api_admin.utils.get_form_config import get_form_config
@@ -48,9 +48,13 @@ class AddView(APIView):
48
48
  serializer = self.serializer_class()
49
49
  data['fields'] = get_form_fields(serializer)
50
50
  data['config'] = get_form_config(self.model_admin)
51
- inlines = get_inlines(request, self.model_admin)
52
- if len(inlines):
53
- data['inlines'] = inlines
51
+
52
+ # Include the model_admin's inlines in the form representation
53
+ if not self.model_admin.is_inline:
54
+ inlines = get_inlines(request, self.model_admin)
55
+ if len(inlines):
56
+ data['inlines'] = inlines
57
+
54
58
  return Response(data, status=status.HTTP_200_OK)
55
59
 
56
60
  def post(self, request):
@@ -58,47 +62,45 @@ class AddView(APIView):
58
62
  Handle POST requests to add a new instance of the model.
59
63
  """
60
64
  with transaction.atomic(using=router.db_for_write(self.model_admin.model)):
61
- # if the user doesn't have added permission respond with permission denied
65
+ # If the user doesn't have add_permission respond with permission denied
62
66
  if not self.model_admin.has_add_permission(request):
63
67
  raise PermissionDenied
64
68
 
65
- # validate data and send
69
+ # Validate the new_object data
66
70
  serializer = self.serializer_class(
67
71
  data=request.data.get('data', {}))
68
72
  if serializer.is_valid():
69
- # create the new object
73
+ # Create the `data` object in the request body used to create the new_object
70
74
  opts = self.model_admin.model._meta
71
75
  new_object = serializer.save()
72
76
  msg = _(
73
77
  f'The {opts.verbose_name} “{str(new_object)}” was added successfully.')
74
78
 
75
- # setup arguments used to log additions
76
- change_object = new_object
77
-
78
- # log addition of the new instance
79
- self.model_admin.log_addition(request, change_object, [{'added': {
79
+ # Log addition of the new instance
80
+ self.model_admin.log_addition(request, new_object, [{'added': {
80
81
  'name': str(new_object._meta.verbose_name),
81
82
  'object': str(new_object),
82
83
  }}])
83
84
 
84
- # process bulk additions
85
+ # Process inline bulk additions
85
86
  created_inlines = []
86
87
  if request.data.get("create_inlines", None):
88
+ # Validate the create_inlines data
87
89
  valid_serializers = validate_bulk_edits(
88
90
  request, self.model_admin, new_object)
89
- # save the inline data in a transaction.
91
+ # Save the inline data (inside a transaction).
90
92
  for inline_serializer in valid_serializers:
91
93
  inline_serializer.save()
92
- # return the data to the user.
94
+ # Return the data to the user.
93
95
  created_inlines = [
94
96
  inline_serializer.data for inline_serializer in valid_serializers]
95
97
 
96
- # return the appropriate 201 response based on the data
98
+ # Return the appropriate 201 response based on the data
97
99
  data = {'data': serializer.data, 'detail': msg}
98
100
  if len(created_inlines):
99
101
  data['created_inlines'] = created_inlines
100
102
 
101
103
  return Response(data, status=status.HTTP_201_CREATED)
102
- else:
103
- # return a 400 response indicating failure
104
- return Response({"errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
104
+
105
+ # return a 400 response indicating failure
106
+ return Response({"errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
@@ -49,9 +49,13 @@ class ChangeView(APIView):
49
49
  data = dict()
50
50
  data['fields'] = get_form_fields(serializer, change=True)
51
51
  data['config'] = get_form_config(self.model_admin)
52
- inlines = get_inlines(request, self.model_admin, obj=obj)
53
- if inlines:
54
- data['inlines'] = inlines
52
+
53
+ # Include the model_admin's inlines in the form representation
54
+ if not self.model_admin.is_inline:
55
+ inlines = get_inlines(request, self.model_admin, obj=obj)
56
+ if inlines:
57
+ data['inlines'] = inlines
58
+
55
59
  return Response(data, status=status.HTTP_200_OK)
56
60
 
57
61
  def update(self, request, object_id):
@@ -14,8 +14,8 @@ class DetailView(APIView):
14
14
  """
15
15
  GET one instance of this model using pk and to_fields.
16
16
  """
17
- permission_classes = []
18
17
  serializer_class = None
18
+ permission_classes = []
19
19
  model_admin = None
20
20
 
21
21
  def get(self, request, object_id):
@@ -48,8 +48,8 @@ class DetailView(APIView):
48
48
  if self.model_admin.view_on_site:
49
49
  model_type = ContentType.objects.get_for_model(
50
50
  model=self.model_admin.model)
51
- data['view_on_site'] = reverse('%s:view_on_site' % self.model_admin.admin_site.name, kwargs={
52
- 'content_type_id': model_type.pk, 'object_id': obj.pk}, request=request)
51
+ data['view_on_site'] = reverse('%s:view_on_site' % self.model_admin.admin_site.name, kwargs={
52
+ 'content_type_id': model_type.pk, 'object_id': obj.pk}, request=request)
53
53
  data['list_url'] = reverse((pattern + 'list') % info, request=request)
54
54
  data['history_url'] = reverse(
55
55
  (pattern + 'history') % info, kwargs={'object_id': data['pk']}, request=request)
@@ -8,15 +8,14 @@ from rest_framework.exceptions import PermissionDenied
8
8
  from django_api_admin.models import LogEntry
9
9
  from django_api_admin.utils.quote import unquote
10
10
  from django_api_admin.utils.get_content_type_for_model import get_content_type_for_model
11
- from rest_framework.views import APIView
12
11
 
13
12
 
14
13
  class HistoryView(APIView):
15
14
  """
16
15
  History of actions that happened to this object.
17
16
  """
18
- permission_classes = []
19
17
  serializer_class = None
18
+ permission_classes = []
20
19
  model_admin = None
21
20
 
22
21
  def get(self, request, object_id):
@@ -1,12 +1,8 @@
1
- from django.utils.translation import gettext_lazy as _
2
-
3
1
  from rest_framework import status
4
2
  from rest_framework.views import APIView
5
3
  from rest_framework.reverse import reverse
6
4
  from rest_framework.response import Response
7
5
 
8
- from rest_framework.views import APIView
9
-
10
6
 
11
7
  class ListView(APIView):
12
8
  """
@@ -1,7 +1,18 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Portions of this file are from Django (https://www.djangoproject.com/)
3
+ # Copyright (c) Django Software Foundation and individual contributors.
4
+ # All rights reserved.
5
+ # Licensed under the BSD 3-Clause License.
6
+ #
7
+ # Additional code copyright (c) 2021 Muhammad Salah
8
+ # Licensed under the MIT License
9
+ #
10
+ # This file includes both Django code and your my own contributions.
11
+ # -----------------------------------------------------------------------------
12
+
1
13
  import copy
2
14
 
3
15
  from django.contrib.auth import get_permission_codename
4
- from django.utils.translation import gettext as _
5
16
 
6
17
  from rest_framework.serializers import ModelSerializer
7
18
 
@@ -85,7 +96,7 @@ class BaseAPIModelAdmin:
85
96
 
86
97
  # dynamically construct a model serializer
87
98
  self.serializer_class = type(data['parent_class'])(
88
- f'{self.model.__name__}AdminSerializer',
99
+ f'{'Inline' if self.is_inline else ''}{self.model.__name__}AdminSerializer',
89
100
  (data['parent_class'],),
90
101
  attrs
91
102
  )
@@ -229,8 +240,8 @@ class BaseAPIModelAdmin:
229
240
 
230
241
  defaults = {
231
242
  'serializer_class': self.get_serializer_class(),
232
- 'permission_classes': self.admin_site.default_permission_classes,
233
- 'authentication_classes': self.admin_site.authentication_classes,
243
+ 'permission_classes': self.admin_site.get_permission_classes(),
244
+ 'authentication_classes': self.admin_site.get_authentication_classes(),
234
245
  'model_admin': self,
235
246
  }
236
247
  return ListView.as_view(**defaults)
@@ -240,8 +251,8 @@ class BaseAPIModelAdmin:
240
251
 
241
252
  defaults = {
242
253
  'serializer_class': self.get_serializer_class(),
243
- 'permission_classes': self.admin_site.default_permission_classes,
244
- 'authentication_classes': self.admin_site.authentication_classes,
254
+ 'permission_classes': self.admin_site.get_permission_classes(),
255
+ 'authentication_classes': self.admin_site.get_authentication_classes(),
245
256
  'model_admin': self
246
257
  }
247
258
  return DetailView.as_view(**defaults)
@@ -251,8 +262,8 @@ class BaseAPIModelAdmin:
251
262
 
252
263
  defaults = {
253
264
  'serializer_class': self.get_serializer_class(),
254
- 'permission_classes': self.admin_site.default_permission_classes,
255
- 'authentication_classes': self.admin_site.authentication_classes,
265
+ 'permission_classes': self.admin_site.get_permission_classes(),
266
+ 'authentication_classes': self.admin_site.get_authentication_classes(),
256
267
  'model_admin': self,
257
268
  }
258
269
  return AddView.as_view(**defaults)
@@ -262,8 +273,8 @@ class BaseAPIModelAdmin:
262
273
 
263
274
  defaults = {
264
275
  'serializer_class': self.get_serializer_class(),
265
- 'permission_classes': self.admin_site.default_permission_classes,
266
- 'authentication_classes': self.admin_site.authentication_classes,
276
+ 'permission_classes': self.admin_site.get_permission_classes(),
277
+ 'authentication_classes': self.admin_site.get_authentication_classes(),
267
278
  'model_admin': self,
268
279
  }
269
280
  return ChangeView.as_view(**defaults)
@@ -272,8 +283,8 @@ class BaseAPIModelAdmin:
272
283
  from django_api_admin.admin_views.model_admin_views.delete import DeleteView
273
284
 
274
285
  defaults = {
275
- 'permission_classes': self.admin_site.default_permission_classes,
276
- 'authentication_classes': self.admin_site.authentication_classes,
286
+ 'permission_classes': self.admin_site.get_permission_classes(),
287
+ 'authentication_classes': self.admin_site.get_authentication_classes(),
277
288
  'model_admin': self
278
289
  }
279
290
  return DeleteView.as_view(**defaults)
@@ -1,3 +1,15 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Portions of this file are from Django (https://www.djangoproject.com/)
3
+ # Copyright (c) Django Software Foundation and individual contributors.
4
+ # All rights reserved.
5
+ # Licensed under the BSD 3-Clause License.
6
+ #
7
+ # Additional code copyright (c) 2021 Muhammad Salah
8
+ # Licensed under the MIT License
9
+ #
10
+ # This file includes both Django code and your my own contributions.
11
+ # -----------------------------------------------------------------------------
12
+
1
13
  from django.core.exceptions import ValidationError
2
14
  from django.utils.text import format_lazy
3
15
 
@@ -57,21 +69,18 @@ class InlineAPIModelAdmin(BaseAPIModelAdmin):
57
69
  def get_urls(self):
58
70
  from django.urls import path
59
71
 
60
- info = (self.parent_model._meta.app_label, self.parent_model._meta.model_name,
61
- self.opts.app_label, self.opts.model_name)
62
- prefix = f'{self.model._meta.app_label}/{self.model._meta.model_name}'
72
+ info = f'{self.parent_model._meta.app_label}_{self.parent_model._meta.model_name}_{self.opts.app_label}_{self.opts.model_name}'
73
+ prefix = f'{self.model._meta.model_name}'
63
74
 
64
75
  return [
65
- path(f'{prefix}/list/', self.get_list_view(),
66
- name='%s_%s_%s_%s_list' % info),
67
- path(f'{prefix}/add/', self.get_add_view(),
68
- name='%s_%s_%s_%s_add' % info),
69
- path(f'{prefix}/<path:object_id>/detail/', self.get_detail_view(),
70
- name='%s_%s_%s_%s_detail' % info),
71
- path(f'{prefix}/<path:object_id>/change/', self.get_change_view(),
72
- name='%s_%s_%s_%s_change' % info),
73
- path(f'{prefix}/<path:object_id>/delete/', self.get_delete_view(),
74
- name='%s_%s_%s_%s_delete' % info),
76
+ path(f'{prefix}/list/', self.get_list_view(), name=f'{info}_list'),
77
+ path(f'{prefix}/add/', self.get_add_view(), name=f'{info}_add'),
78
+ path(f'{prefix}/<path:object_id>/detail/',
79
+ self.get_detail_view(), name=f'{info}_detail'),
80
+ path(f'{prefix}/<path:object_id>/change/',
81
+ self.get_change_view(), name=f'{info}_change'),
82
+ path(f'{prefix}/<path:object_id>/delete/',
83
+ self.get_delete_view(), name=f'{info}_delete'),
75
84
  ]
76
85
 
77
86
  @property