djresttoolkit 0.17.5__tar.gz → 1.1.0__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.
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/PKG-INFO +41 -68
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/README.md +40 -65
- djresttoolkit-1.1.0/demo/apps/todos/urls.py +11 -0
- djresttoolkit-1.1.0/demo/apps/todos/views.py +18 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/settings.py +4 -22
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/pyproject.toml +1 -3
- djresttoolkit-1.1.0/src/djresttoolkit/envconfig/__init__.py +4 -0
- djresttoolkit-1.1.0/src/djresttoolkit/envconfig/_base_env_config.py +84 -0
- djresttoolkit-1.1.0/src/djresttoolkit/views/mixins/__init__.py +3 -0
- djresttoolkit-1.1.0/src/djresttoolkit/views/mixins/_retrieve_object_mixin.py +59 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/uv.lock +1 -5
- djresttoolkit-0.17.5/demo/apps/todos/urls.py +0 -7
- djresttoolkit-0.17.5/demo/apps/todos/views.py +0 -0
- djresttoolkit-0.17.5/demo/env_config/__init__.py +0 -3
- djresttoolkit-0.17.5/demo/env_config/env_settings.py +0 -54
- djresttoolkit-0.17.5/src/djresttoolkit/envconfig/__init__.py +0 -3
- djresttoolkit-0.17.5/src/djresttoolkit/envconfig/_env_settings.py +0 -84
- djresttoolkit-0.17.5/src/djresttoolkit/views/mixins/__init__.py +0 -6
- djresttoolkit-0.17.5/src/djresttoolkit/views/mixins/_retrieve_object_mixin.py +0 -41
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/.gitignore +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/.python-version +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/.vscode/settings.json +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/LICENSE +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/admin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/apps.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/dbseed/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/dbseed/tag_seed.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/dbseed/todo_seed.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/dbseed/todo_tag_seed.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/migrations/0001_initial.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/migrations/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/models.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps/todos/tests.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/asgi.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/serializers.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/urls.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/views.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/apps_config/wsgi.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/manage.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/autocomplete.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/base.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/changelists.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/dark_mode.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/dashboard.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/forms.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/login.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/nav_sidebar.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/responsive.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/responsive_rtl.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/rtl.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/unusable_password_field.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/vendor/select2/select2.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/vendor/select2/select2.min.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/css/widgets.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/LICENSE +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/README.txt +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/calendar-icons.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/gis/move_vertex_off.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/gis/move_vertex_on.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-addlink.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-alert.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-calendar.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-changelink.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-clock.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-deletelink.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-hidelink.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-no.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-unknown-alt.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-unknown.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-viewlink.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/icon-yes.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/inline-delete.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/search.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/selector-icons.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/sorting-icons.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/tooltag-add.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/img/tooltag-arrowright.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/SelectBox.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/SelectFilter2.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/actions.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/admin/DateTimeShortcuts.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/admin/RelatedObjectLookups.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/autocomplete.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/calendar.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/cancel.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/change_form.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/core.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/filters.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/inlines.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/jquery.init.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/nav_sidebar.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/popup_response.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/prepopulate.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/prepopulate_init.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/theme.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/unusable_password_field.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/urlify.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/jquery/LICENSE.txt +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/LICENSE.md +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/af.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ar.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/az.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bg.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bn.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bs.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ca.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/cs.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/da.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/de.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/dsb.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/el.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/en.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/es.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/et.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/eu.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fa.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fi.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fr.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/gl.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/he.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hi.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hr.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hsb.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hu.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hy.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/id.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/is.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/it.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ja.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ka.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/km.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ko.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/lt.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/lv.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/mk.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ms.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/nb.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ne.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/nl.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pl.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ps.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pt-BR.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pt.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ro.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ru.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sk.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sl.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sq.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sr-Cyrl.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sr.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sv.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/th.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/tk.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/tr.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/uk.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/vi.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-CN.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-TW.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/select2.full.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/select2/select2.full.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/xregexp/LICENSE.txt +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css.map +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/bootstrap-tweaks.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/bootstrap.min.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/bootstrap.min.css.map +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/default.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/font-awesome-4.0.3.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/css/prettify.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/css/base.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/css/highlight.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/css/jquery.json-view.min.css +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/img/favicon.ico +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/img/grid.png +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/js/api.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/js/highlight.pack.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/docs/js/jquery.json-view.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.eot +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.ttf +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.woff +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.eot +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.svg +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.ttf +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/img/glyphicons-halflings-white.png +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/img/glyphicons-halflings.png +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/img/grid.png +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/ajax-form.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/bootstrap.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/coreapi-0.1.1.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/csrf.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/default.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/jquery-3.7.1.min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/load-ajax-form.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/demo/staticfiles/rest_framework/js/prettify-min.js +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/admin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/apps.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/_cache_action_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/_cache_invalidate_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/_cache_key_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/_cache_list_retrieve_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/cache/mixins/_cache_ops_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/dbseed/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/dbseed/models/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/dbseed/models/_choice_field.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/dbseed/models/_gen.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/dbseed/models/_seed_model.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/mail/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/mail/_email_sender.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/mail/_models.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/mail/_types.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/management/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/management/commands/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/management/commands/dbflush.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/management/commands/dbseed.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/middlewares/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/middlewares/_response_time_middleware.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/migrations/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/models/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/models/mixins/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/models/mixins/_model_choice_fields_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/pagination/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/pagination/_page_number_pagination.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/pagination/_paginated_data_builder.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/py.typed +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/renderers/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/renderers/_throttle_info_json_renderer.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/serializers/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/serializers/mixins/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/serializers/mixins/_absolute_url_file_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/serializers/mixins/_bulk_create_mixin.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/throttling/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/throttling/_throttle_inspector.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/urls/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/urls/_build_absolute_uri.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/views/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/views/_apiviews/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/views/_apiviews/_choice_fields_apiview.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/views/_exceptions/__init__.py +0 -0
- {djresttoolkit-0.17.5 → djresttoolkit-1.1.0}/src/djresttoolkit/views/_exceptions/_exception_handler.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: djresttoolkit
|
3
|
-
Version:
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: A collection of Django and DRF utilities to simplify API development.
|
5
5
|
Project-URL: Homepage, https://github.com/shaileshpandit141/djresttoolkit
|
6
6
|
Project-URL: Documentation, https://shaileshpandit141.github.io/djresttoolkit
|
@@ -47,9 +47,7 @@ Classifier: Topic :: Utilities
|
|
47
47
|
Classifier: Typing :: Typed
|
48
48
|
Requires-Python: >=3.13
|
49
49
|
Requires-Dist: faker>=37.5.3
|
50
|
-
Requires-Dist: pydantic-settings>=2.10.1
|
51
50
|
Requires-Dist: pydantic>=2.11.7
|
52
|
-
Requires-Dist: pyyaml>=6.0.2
|
53
51
|
Provides-Extra: dev
|
54
52
|
Requires-Dist: mypy; extra == 'dev'
|
55
53
|
Requires-Dist: pytest; extra == 'dev'
|
@@ -72,8 +70,8 @@ djresttoolkit is a collection of utilities and helpers for Django and Django RES
|
|
72
70
|
- **DB Flush Command (`dbflush`)**
|
73
71
|
Management command to flush all models or a specific model, resetting auto-increment IDs safely with transaction support.
|
74
72
|
|
75
|
-
- **
|
76
|
-
|
73
|
+
- **BaseEnvConfig**
|
74
|
+
Singleton environment loader that reads and parses environment variables.
|
77
75
|
|
78
76
|
- **EmailSender**
|
79
77
|
Custom class to send templated emails (`text` and `html`) with context. Supports error handling and logging.
|
@@ -186,10 +184,6 @@ python manage.py dbseed --count 10
|
|
186
184
|
python manage.py dbseed --model User --seed 42
|
187
185
|
```
|
188
186
|
|
189
|
-
Here’s a **concise API reference** for your database flush management command for `djresttoolkit`:
|
190
|
-
|
191
|
-
---
|
192
|
-
|
193
187
|
### 2. DB Flush Command — API Reference
|
194
188
|
|
195
189
|
```python
|
@@ -246,77 +240,54 @@ or
|
|
246
240
|
Flushed 120 records from all models and reset IDs.
|
247
241
|
```
|
248
242
|
|
249
|
-
### 3.
|
243
|
+
### 3. BaseEnvConfig — API Reference
|
250
244
|
|
251
245
|
```python
|
252
|
-
from djresttoolkit.envconfig import
|
246
|
+
from djresttoolkit.envconfig import BaseEnvConfig
|
253
247
|
```
|
254
248
|
|
255
|
-
#### `
|
256
|
-
|
257
|
-
A **base settings class** for managing application configuration using:
|
258
|
-
|
259
|
-
- YAML files (default `.environ.yaml`)
|
260
|
-
- Environment variables (default `.env`)
|
261
|
-
|
262
|
-
Supports **nested configuration** using double underscores (`__`) in environment variable names.
|
263
|
-
|
264
|
-
#### Class Attributes
|
265
|
-
|
266
|
-
- Attributes
|
267
|
-
- `env_file`
|
268
|
-
- Type: `str`
|
269
|
-
- Default: `.env`
|
270
|
-
- Description: Environment variable file path.
|
271
|
-
- `yaml_file`
|
272
|
-
- Type: `str`
|
273
|
-
- Default: `.environ.yaml`
|
274
|
-
- Description: YAML configuration file path.
|
275
|
-
- `model_config`
|
276
|
-
- Type: `SettingsConfigDict`
|
277
|
-
- Description: Pydantic settings configuration (file encoding, nested delimiter).
|
278
|
-
|
279
|
-
#### Methods
|
249
|
+
#### `BaseEnvConfig`
|
280
250
|
|
281
|
-
|
251
|
+
Singleton environment loader that reads and parses environment variables with support for booleans, numbers, and JSON.
|
282
252
|
|
283
|
-
|
253
|
+
> ⚠️ **Note:** Note: If you are using a .env file, load it first with python-dotenv:
|
254
|
+
>
|
255
|
+
> ```python
|
256
|
+
> from dotenv import load_dotenv
|
257
|
+
> load_dotenv()
|
258
|
+
> ```
|
284
259
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
#### Returns
|
292
|
-
|
293
|
-
- Instance of `EnvBaseSettings` (or subclass) with loaded configuration.
|
294
|
-
|
295
|
-
#### Raises
|
296
|
-
|
297
|
-
- `UserWarning` if YAML file not found and `warning=True`.
|
260
|
+
or
|
261
|
+
>
|
262
|
+
> ```python
|
263
|
+
> from djresttoolkit.envconfig import load_dotenv
|
264
|
+
> load_dotenv()
|
265
|
+
> ```
|
298
266
|
|
299
|
-
|
267
|
+
#### Usage Example
|
300
268
|
|
301
269
|
```python
|
302
|
-
from djresttoolkit.envconfig import
|
270
|
+
from djresttoolkit.envconfig import load_dotenv, BaseEnvConfig
|
303
271
|
|
304
|
-
|
305
|
-
debug: bool = False
|
306
|
-
database_url: str
|
272
|
+
load_dotenv()
|
307
273
|
|
308
|
-
|
309
|
-
|
274
|
+
class EnvConfig(BaseEnvConfig):
|
275
|
+
DEBUG: bool = False
|
276
|
+
DATABASE_URL: str
|
310
277
|
|
311
|
-
|
312
|
-
print(
|
278
|
+
config = EnvConfig()
|
279
|
+
print(config.DEBUG)
|
280
|
+
print(config.DATABASE_URL)
|
281
|
+
|
282
|
+
config.reload()
|
313
283
|
```
|
314
284
|
|
315
285
|
#### Features
|
316
286
|
|
317
|
-
-
|
318
|
-
-
|
319
|
-
-
|
287
|
+
- Thread-safe singleton.
|
288
|
+
- Automatic type parsing for environment variables.
|
289
|
+
- Supports default values and runtime reloading.
|
290
|
+
- Designed for subclassing with project-specific settings.
|
320
291
|
|
321
292
|
### 4. EmailSender — API Reference
|
322
293
|
|
@@ -830,6 +801,7 @@ Retrieve a single model object using the provided filter criteria.
|
|
830
801
|
|
831
802
|
```python
|
832
803
|
from rest_framework.views import APIView
|
804
|
+
from rest_framework.response import Respone
|
833
805
|
from django.http import JsonResponse
|
834
806
|
from myapp.models import Book
|
835
807
|
from djresttoolkit.mixins import RetrieveObjectMixin
|
@@ -837,17 +809,18 @@ from djresttoolkit.mixins import RetrieveObjectMixin
|
|
837
809
|
class BookDetailView(RetrieveObjectMixin[Book], APIView):
|
838
810
|
queryset = Book.objects.all()
|
839
811
|
|
840
|
-
def
|
812
|
+
def not_found_detail(self) -> dict[str, str] | str:
|
813
|
+
return "The requested Book was not found."
|
814
|
+
|
815
|
+
def get(self, request, *args, **kwargs) -> Respone:
|
841
816
|
book = self.get_object(id=kwargs["id"])
|
842
|
-
|
843
|
-
return JsonResponse({"title": book.title, "author": book.author})
|
844
|
-
return JsonResponse({"detail": "Not found"}, status=404)
|
817
|
+
return Respone({"title": book.title, "author": book.author})
|
845
818
|
```
|
846
819
|
|
847
820
|
#### Features of Retrieve Object Mixin
|
848
821
|
|
849
822
|
- Simplifies object retrieval in class-based views or DRF views.
|
850
|
-
-
|
823
|
+
- Raise `http404` if requested resource does not extst.
|
851
824
|
- Works with any Django model and queryset.
|
852
825
|
|
853
826
|
### 13. build_absolute_uri — API Reference
|
@@ -14,8 +14,8 @@ djresttoolkit is a collection of utilities and helpers for Django and Django RES
|
|
14
14
|
- **DB Flush Command (`dbflush`)**
|
15
15
|
Management command to flush all models or a specific model, resetting auto-increment IDs safely with transaction support.
|
16
16
|
|
17
|
-
- **
|
18
|
-
|
17
|
+
- **BaseEnvConfig**
|
18
|
+
Singleton environment loader that reads and parses environment variables.
|
19
19
|
|
20
20
|
- **EmailSender**
|
21
21
|
Custom class to send templated emails (`text` and `html`) with context. Supports error handling and logging.
|
@@ -128,10 +128,6 @@ python manage.py dbseed --count 10
|
|
128
128
|
python manage.py dbseed --model User --seed 42
|
129
129
|
```
|
130
130
|
|
131
|
-
Here’s a **concise API reference** for your database flush management command for `djresttoolkit`:
|
132
|
-
|
133
|
-
---
|
134
|
-
|
135
131
|
### 2. DB Flush Command — API Reference
|
136
132
|
|
137
133
|
```python
|
@@ -188,77 +184,54 @@ or
|
|
188
184
|
Flushed 120 records from all models and reset IDs.
|
189
185
|
```
|
190
186
|
|
191
|
-
### 3.
|
187
|
+
### 3. BaseEnvConfig — API Reference
|
192
188
|
|
193
189
|
```python
|
194
|
-
from djresttoolkit.envconfig import
|
190
|
+
from djresttoolkit.envconfig import BaseEnvConfig
|
195
191
|
```
|
196
192
|
|
197
|
-
#### `
|
198
|
-
|
199
|
-
A **base settings class** for managing application configuration using:
|
200
|
-
|
201
|
-
- YAML files (default `.environ.yaml`)
|
202
|
-
- Environment variables (default `.env`)
|
203
|
-
|
204
|
-
Supports **nested configuration** using double underscores (`__`) in environment variable names.
|
205
|
-
|
206
|
-
#### Class Attributes
|
207
|
-
|
208
|
-
- Attributes
|
209
|
-
- `env_file`
|
210
|
-
- Type: `str`
|
211
|
-
- Default: `.env`
|
212
|
-
- Description: Environment variable file path.
|
213
|
-
- `yaml_file`
|
214
|
-
- Type: `str`
|
215
|
-
- Default: `.environ.yaml`
|
216
|
-
- Description: YAML configuration file path.
|
217
|
-
- `model_config`
|
218
|
-
- Type: `SettingsConfigDict`
|
219
|
-
- Description: Pydantic settings configuration (file encoding, nested delimiter).
|
220
|
-
|
221
|
-
#### Methods
|
193
|
+
#### `BaseEnvConfig`
|
222
194
|
|
223
|
-
|
195
|
+
Singleton environment loader that reads and parses environment variables with support for booleans, numbers, and JSON.
|
224
196
|
|
225
|
-
|
197
|
+
> ⚠️ **Note:** Note: If you are using a .env file, load it first with python-dotenv:
|
198
|
+
>
|
199
|
+
> ```python
|
200
|
+
> from dotenv import load_dotenv
|
201
|
+
> load_dotenv()
|
202
|
+
> ```
|
226
203
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
#### Returns
|
234
|
-
|
235
|
-
- Instance of `EnvBaseSettings` (or subclass) with loaded configuration.
|
236
|
-
|
237
|
-
#### Raises
|
238
|
-
|
239
|
-
- `UserWarning` if YAML file not found and `warning=True`.
|
204
|
+
or
|
205
|
+
>
|
206
|
+
> ```python
|
207
|
+
> from djresttoolkit.envconfig import load_dotenv
|
208
|
+
> load_dotenv()
|
209
|
+
> ```
|
240
210
|
|
241
|
-
|
211
|
+
#### Usage Example
|
242
212
|
|
243
213
|
```python
|
244
|
-
from djresttoolkit.envconfig import
|
214
|
+
from djresttoolkit.envconfig import load_dotenv, BaseEnvConfig
|
245
215
|
|
246
|
-
|
247
|
-
debug: bool = False
|
248
|
-
database_url: str
|
216
|
+
load_dotenv()
|
249
217
|
|
250
|
-
|
251
|
-
|
218
|
+
class EnvConfig(BaseEnvConfig):
|
219
|
+
DEBUG: bool = False
|
220
|
+
DATABASE_URL: str
|
252
221
|
|
253
|
-
|
254
|
-
print(
|
222
|
+
config = EnvConfig()
|
223
|
+
print(config.DEBUG)
|
224
|
+
print(config.DATABASE_URL)
|
225
|
+
|
226
|
+
config.reload()
|
255
227
|
```
|
256
228
|
|
257
229
|
#### Features
|
258
230
|
|
259
|
-
-
|
260
|
-
-
|
261
|
-
-
|
231
|
+
- Thread-safe singleton.
|
232
|
+
- Automatic type parsing for environment variables.
|
233
|
+
- Supports default values and runtime reloading.
|
234
|
+
- Designed for subclassing with project-specific settings.
|
262
235
|
|
263
236
|
### 4. EmailSender — API Reference
|
264
237
|
|
@@ -772,6 +745,7 @@ Retrieve a single model object using the provided filter criteria.
|
|
772
745
|
|
773
746
|
```python
|
774
747
|
from rest_framework.views import APIView
|
748
|
+
from rest_framework.response import Respone
|
775
749
|
from django.http import JsonResponse
|
776
750
|
from myapp.models import Book
|
777
751
|
from djresttoolkit.mixins import RetrieveObjectMixin
|
@@ -779,17 +753,18 @@ from djresttoolkit.mixins import RetrieveObjectMixin
|
|
779
753
|
class BookDetailView(RetrieveObjectMixin[Book], APIView):
|
780
754
|
queryset = Book.objects.all()
|
781
755
|
|
782
|
-
def
|
756
|
+
def not_found_detail(self) -> dict[str, str] | str:
|
757
|
+
return "The requested Book was not found."
|
758
|
+
|
759
|
+
def get(self, request, *args, **kwargs) -> Respone:
|
783
760
|
book = self.get_object(id=kwargs["id"])
|
784
|
-
|
785
|
-
return JsonResponse({"title": book.title, "author": book.author})
|
786
|
-
return JsonResponse({"detail": "Not found"}, status=404)
|
761
|
+
return Respone({"title": book.title, "author": book.author})
|
787
762
|
```
|
788
763
|
|
789
764
|
#### Features of Retrieve Object Mixin
|
790
765
|
|
791
766
|
- Simplifies object retrieval in class-based views or DRF views.
|
792
|
-
-
|
767
|
+
- Raise `http404` if requested resource does not extst.
|
793
768
|
- Works with any Django model and queryset.
|
794
769
|
|
795
770
|
### 13. build_absolute_uri — API Reference
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from django.forms.models import model_to_dict
|
2
|
+
from rest_framework.permissions import AllowAny
|
3
|
+
from rest_framework.request import Request
|
4
|
+
from rest_framework.response import Response
|
5
|
+
from rest_framework.views import APIView
|
6
|
+
|
7
|
+
from djresttoolkit.views.mixins import RetrieveObjectMixin
|
8
|
+
|
9
|
+
from .models import Todo
|
10
|
+
|
11
|
+
|
12
|
+
class TodoDetailView(RetrieveObjectMixin[Todo], APIView):
|
13
|
+
permission_classes = [AllowAny]
|
14
|
+
queryset = Todo.objects.all()
|
15
|
+
|
16
|
+
def get(self, request: Request, id: int) -> Response:
|
17
|
+
todo = self.get_object(id=id)
|
18
|
+
return Response(data=model_to_dict(todo))
|
@@ -1,8 +1,6 @@
|
|
1
1
|
import sys
|
2
2
|
from pathlib import Path
|
3
3
|
|
4
|
-
from env_config import env_settings
|
5
|
-
|
6
4
|
# Configuration Settings File for the django backend
|
7
5
|
# --------------------------------------------------
|
8
6
|
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
@@ -14,7 +12,7 @@ sys.path.insert(0, str(SRC_DIR))
|
|
14
12
|
|
15
13
|
# Security Configuration Settings
|
16
14
|
# -------------------------------
|
17
|
-
SECRET_KEY =
|
15
|
+
SECRET_KEY = "asdkjasdjgasdgjioarejalk54884a651asdgklnaskdg"
|
18
16
|
|
19
17
|
# DEBUG Configuration Settings
|
20
18
|
# ----------------------------
|
@@ -22,11 +20,11 @@ DEBUG = True
|
|
22
20
|
|
23
21
|
# Allowed Host Configuration Settings
|
24
22
|
# -----------------------------------
|
25
|
-
ALLOWED_HOSTS =
|
23
|
+
ALLOWED_HOSTS = ["*"]
|
26
24
|
|
27
25
|
# Configure CORS Settings
|
28
26
|
# -----------------------
|
29
|
-
CORS_ALLOWED_ORIGINS =
|
27
|
+
# CORS_ALLOWED_ORIGINS = []
|
30
28
|
|
31
29
|
# Login Redirect URL Configuration Setting
|
32
30
|
# ----------------------------------------
|
@@ -200,29 +198,13 @@ REST_FRAMEWORK = {
|
|
200
198
|
# -------------------------------------
|
201
199
|
AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.ModelBackend"]
|
202
200
|
|
203
|
-
# EMAIL Configuration Settings
|
204
|
-
# ----------------------------
|
205
|
-
EMAIL_BACKEND = env_settings.email.backend # type: ignore[]
|
206
|
-
EMAIL_HOST = env_settings.email.host
|
207
|
-
EMAIL_PORT = env_settings.email.port
|
208
|
-
EMAIL_USE_TLS = env_settings.email.use_tls
|
209
|
-
EMAIL_USE_SSL = env_settings.email.use_ssl
|
210
|
-
EMAIL_HOST_USER = env_settings.email.host_user
|
211
|
-
EMAIL_HOST_PASSWORD = env_settings.email.host_password
|
212
|
-
DEFAULT_FROM_EMAIL = env_settings.email.default_from_email
|
213
|
-
|
214
|
-
# Google OAuth2 Configuration Settings
|
215
|
-
# ------------------------------------
|
216
|
-
GOOGLE_CLIENT_ID = env_settings.google.client_id
|
217
|
-
GOOGLE_CLIENT_SECRET = env_settings.google.client_secret
|
218
|
-
GOOGLE_REDIRECT_URI = env_settings.google.redirect_url
|
219
201
|
|
220
202
|
# Redis configuration for production
|
221
203
|
# ----------------------------------
|
222
204
|
CACHES = {
|
223
205
|
"default": {
|
224
206
|
"BACKEND": "django_redis.cache.RedisCache",
|
225
|
-
"LOCATION":
|
207
|
+
"LOCATION": "redis://localhost:6379/1",
|
226
208
|
"OPTIONS": {
|
227
209
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
228
210
|
},
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "djresttoolkit"
|
7
|
-
version = "
|
7
|
+
version = "1.1.0"
|
8
8
|
description = "A collection of Django and DRF utilities to simplify API development."
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
10
10
|
license = { file = "LICENSE" }
|
@@ -48,8 +48,6 @@ requires-python = ">=3.13"
|
|
48
48
|
dependencies = [
|
49
49
|
"faker>=37.5.3",
|
50
50
|
"pydantic>=2.11.7",
|
51
|
-
"pydantic-settings>=2.10.1",
|
52
|
-
"pyyaml>=6.0.2",
|
53
51
|
]
|
54
52
|
|
55
53
|
# CLI scripts entry point configuration
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import threading
|
2
|
+
import json
|
3
|
+
from os import getenv
|
4
|
+
from typing import Any, Self, get_type_hints
|
5
|
+
import logging
|
6
|
+
|
7
|
+
logger = logging.getLogger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
class BaseEnvConfig:
|
11
|
+
"""Production-ready environment loader."""
|
12
|
+
|
13
|
+
_instance_lock = threading.Lock()
|
14
|
+
_instance = None
|
15
|
+
|
16
|
+
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
|
17
|
+
if cls._instance is None:
|
18
|
+
with cls._instance_lock:
|
19
|
+
if cls._instance is None:
|
20
|
+
cls._instance = super().__new__(cls)
|
21
|
+
return cls._instance
|
22
|
+
|
23
|
+
def __init__(self) -> None:
|
24
|
+
if getattr(self, "_initialized", False):
|
25
|
+
return
|
26
|
+
|
27
|
+
self._env_cache: dict[str, Any] = {}
|
28
|
+
self._sync_env()
|
29
|
+
self._initialized = True
|
30
|
+
|
31
|
+
def _sync_env(self) -> None:
|
32
|
+
hints = get_type_hints(self.__class__)
|
33
|
+
for field, _ in hints.items():
|
34
|
+
raw = getenv(field)
|
35
|
+
|
36
|
+
if raw is None:
|
37
|
+
if hasattr(self, field):
|
38
|
+
value = getattr(self, field)
|
39
|
+
logger.info(f"{field} not set, using default: {value}")
|
40
|
+
else:
|
41
|
+
raise EnvironmentError(
|
42
|
+
f"Missing required environment variable: {field}"
|
43
|
+
)
|
44
|
+
else:
|
45
|
+
if field in self._env_cache:
|
46
|
+
value = self._env_cache[field]
|
47
|
+
else:
|
48
|
+
value = self._parse_env_value(raw)
|
49
|
+
self._env_cache[field] = value
|
50
|
+
|
51
|
+
setattr(self, field, value)
|
52
|
+
|
53
|
+
def _parse_env_value(self, raw: str) -> Any:
|
54
|
+
"""Parse string from environment."""
|
55
|
+
lowered = raw.lower()
|
56
|
+
|
57
|
+
# Boolean parsing
|
58
|
+
if lowered == "true":
|
59
|
+
return True
|
60
|
+
if lowered == "false":
|
61
|
+
return False
|
62
|
+
|
63
|
+
# JSON parsing
|
64
|
+
try:
|
65
|
+
return json.loads(raw)
|
66
|
+
except json.JSONDecodeError:
|
67
|
+
pass
|
68
|
+
|
69
|
+
# Numeric parsing
|
70
|
+
if raw.isdigit():
|
71
|
+
return int(raw)
|
72
|
+
try:
|
73
|
+
return float(raw)
|
74
|
+
except ValueError:
|
75
|
+
pass
|
76
|
+
|
77
|
+
# Fallback: plain string
|
78
|
+
return raw
|
79
|
+
|
80
|
+
def reload(self) -> None:
|
81
|
+
"""Reload environment variables at runtime."""
|
82
|
+
self._env_cache.clear()
|
83
|
+
self._sync_env()
|
84
|
+
logger.info("Environment variables reloaded.")
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from django.core.exceptions import ImproperlyConfigured
|
4
|
+
from django.db.models import Model, QuerySet
|
5
|
+
from django.http import Http404
|
6
|
+
|
7
|
+
|
8
|
+
class RetrieveObjectMixin[T: Model]:
|
9
|
+
"""
|
10
|
+
Retrieve a single model object by filters.
|
11
|
+
|
12
|
+
Requires the `queryset` attribute to be set in the class that inherits this mixin.
|
13
|
+
|
14
|
+
Raises `Http404` when the object is missing.
|
15
|
+
|
16
|
+
This works in both Django views and DRF views.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
```
|
20
|
+
class MyView(RetrieveModelMixin[Book], APIView):
|
21
|
+
queryset = Book.objects.all()
|
22
|
+
|
23
|
+
def get(self, request, *args, **kwargs):
|
24
|
+
obj = self.get_object(id=1)
|
25
|
+
return JsonResponse(obj.to_dict())
|
26
|
+
```
|
27
|
+
"""
|
28
|
+
|
29
|
+
queryset: QuerySet[T] | None = None
|
30
|
+
|
31
|
+
def get_object(self, **filters: Any) -> T:
|
32
|
+
"""Retrieve a model object based on provided filters."""
|
33
|
+
|
34
|
+
if self.queryset is None:
|
35
|
+
raise ImproperlyConfigured(
|
36
|
+
"Queryset attribute is not set in the class.",
|
37
|
+
)
|
38
|
+
|
39
|
+
try:
|
40
|
+
return self.queryset.get(**filters)
|
41
|
+
except self.queryset.model.DoesNotExist:
|
42
|
+
raise Http404(self.not_found_detail())
|
43
|
+
|
44
|
+
def not_found_detail(self) -> dict[str, str] | str:
|
45
|
+
"""
|
46
|
+
Hook for customizing the 404 message.
|
47
|
+
Can be overridden per view.
|
48
|
+
"""
|
49
|
+
|
50
|
+
if self.queryset is None:
|
51
|
+
raise ImproperlyConfigured(
|
52
|
+
"Queryset attribute is not set in the class.",
|
53
|
+
)
|
54
|
+
|
55
|
+
verbose_name = self.queryset.model._meta.verbose_name
|
56
|
+
model_name = (
|
57
|
+
verbose_name.title() if verbose_name else self.queryset.model.__name__
|
58
|
+
)
|
59
|
+
return f"The requested {model_name} was not found."
|
@@ -342,13 +342,11 @@ wheels = [
|
|
342
342
|
|
343
343
|
[[package]]
|
344
344
|
name = "djresttoolkit"
|
345
|
-
version = "0.
|
345
|
+
version = "1.0.0"
|
346
346
|
source = { editable = "." }
|
347
347
|
dependencies = [
|
348
348
|
{ name = "faker" },
|
349
349
|
{ name = "pydantic" },
|
350
|
-
{ name = "pydantic-settings" },
|
351
|
-
{ name = "pyyaml" },
|
352
350
|
]
|
353
351
|
|
354
352
|
[package.optional-dependencies]
|
@@ -380,9 +378,7 @@ requires-dist = [
|
|
380
378
|
{ name = "faker", specifier = ">=37.5.3" },
|
381
379
|
{ name = "mypy", marker = "extra == 'dev'" },
|
382
380
|
{ name = "pydantic", specifier = ">=2.11.7" },
|
383
|
-
{ name = "pydantic-settings", specifier = ">=2.10.1" },
|
384
381
|
{ name = "pytest", marker = "extra == 'dev'" },
|
385
|
-
{ name = "pyyaml", specifier = ">=6.0.2" },
|
386
382
|
{ name = "ruff", marker = "extra == 'dev'" },
|
387
383
|
]
|
388
384
|
provides-extras = ["dev"]
|
File without changes
|