djresttoolkit 1.1.0__tar.gz → 1.2.1__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-1.1.0 → djresttoolkit-1.2.1}/PKG-INFO +30 -5
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/README.md +29 -4
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/models.py +20 -1
- djresttoolkit-1.2.1/demo/apps/todos/serializers.py +9 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/urls.py +2 -1
- djresttoolkit-1.2.1/demo/apps/todos/views.py +43 -0
- djresttoolkit-1.2.1/demo/apps_config/__init__.py +3 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/settings.py +3 -1
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/pyproject.toml +13 -9
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/pagination/_paginated_data_builder.py +10 -4
- djresttoolkit-1.2.1/src/djresttoolkit/serializers/__init__.py +3 -0
- djresttoolkit-1.2.1/src/djresttoolkit/serializers/_enhanced_model_serializer.py +59 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/uv.lock +1 -1
- djresttoolkit-1.1.0/demo/apps/todos/views.py +0 -18
- djresttoolkit-1.1.0/src/djresttoolkit/serializers/__init__.py +0 -0
- djresttoolkit-1.1.0/src/djresttoolkit/views/_apiviews/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/.gitignore +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/.python-version +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/.vscode/settings.json +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/LICENSE +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/admin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/apps.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/dbseed/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/dbseed/tag_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/dbseed/todo_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/dbseed/todo_tag_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/migrations/0001_initial.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/migrations/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps/todos/tests.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/asgi.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/serializers.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/urls.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/views.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/apps_config/wsgi.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/manage.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/autocomplete.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/base.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/changelists.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/dark_mode.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/dashboard.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/forms.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/login.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/nav_sidebar.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/responsive.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/responsive_rtl.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/rtl.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/unusable_password_field.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/vendor/select2/select2.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/vendor/select2/select2.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/widgets.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/LICENSE +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/README.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/calendar-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/gis/move_vertex_off.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/gis/move_vertex_on.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-addlink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-alert.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-calendar.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-changelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-clock.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-deletelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-hidelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-no.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-unknown-alt.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-unknown.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-viewlink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/icon-yes.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/inline-delete.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/search.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/selector-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/sorting-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/tooltag-add.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/tooltag-arrowright.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/SelectBox.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/SelectFilter2.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/actions.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/admin/DateTimeShortcuts.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/admin/RelatedObjectLookups.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/autocomplete.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/calendar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/cancel.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/change_form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/core.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/filters.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/inlines.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/jquery.init.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/nav_sidebar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/popup_response.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/prepopulate.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/prepopulate_init.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/theme.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/unusable_password_field.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/urlify.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/jquery/LICENSE.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/jquery/jquery.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/jquery/jquery.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/LICENSE.md +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/af.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/az.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/bg.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/bn.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/bs.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ca.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/cs.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/da.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/de.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/dsb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/el.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/en.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/es.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/et.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/eu.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/fa.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/fi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/fr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/gl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/he.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/hi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/hr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/hsb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/hu.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/hy.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/id.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/is.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/it.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ja.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ka.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/km.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ko.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/lt.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/lv.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/mk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ms.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/nb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ne.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/nl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/pl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ps.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/pt-BR.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/pt.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ro.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/ru.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sq.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sr-Cyrl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/sv.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/th.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/tk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/tr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/uk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/vi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-CN.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-TW.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/select2.full.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/select2/select2.full.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/xregexp/LICENSE.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css.map +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/bootstrap-tweaks.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/bootstrap.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/bootstrap.min.css.map +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/default.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/font-awesome-4.0.3.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/css/prettify.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/css/base.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/css/highlight.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/css/jquery.json-view.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/img/favicon.ico +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/img/grid.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/js/api.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/js/highlight.pack.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/docs/js/jquery.json-view.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.eot +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.ttf +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.woff +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.eot +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.ttf +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/img/glyphicons-halflings-white.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/img/glyphicons-halflings.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/img/grid.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/ajax-form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/bootstrap.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/coreapi-0.1.1.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/csrf.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/default.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/jquery-3.7.1.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/load-ajax-form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/rest_framework/js/prettify-min.js +0 -0
- {djresttoolkit-1.1.0/demo/apps_config → djresttoolkit-1.2.1/src/djresttoolkit}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/admin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/apps.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit → djresttoolkit-1.2.1/src/djresttoolkit/cache}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/_cache_action_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/_cache_invalidate_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/_cache_key_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/_cache_list_retrieve_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/cache/mixins/_cache_ops_mixin.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/cache → djresttoolkit-1.2.1/src/djresttoolkit/dbseed}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/dbseed/models/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/dbseed/models/_choice_field.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/dbseed/models/_gen.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/dbseed/models/_seed_model.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/envconfig/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/envconfig/_base_env_config.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/mail/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/mail/_email_sender.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/mail/_models.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/mail/_types.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/dbseed → djresttoolkit-1.2.1/src/djresttoolkit/management}/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/management → djresttoolkit-1.2.1/src/djresttoolkit/management/commands}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/management/commands/dbflush.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/management/commands/dbseed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/middlewares/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/middlewares/_response_time_middleware.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/management/commands → djresttoolkit-1.2.1/src/djresttoolkit/migrations}/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/migrations → djresttoolkit-1.2.1/src/djresttoolkit/models}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/models/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/models/mixins/_model_choice_fields_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/pagination/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/pagination/_page_number_pagination.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/py.typed +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/renderers/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/renderers/_throttle_info_json_renderer.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/serializers/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/serializers/mixins/_absolute_url_file_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/serializers/mixins/_bulk_create_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/throttling/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/throttling/_throttle_inspector.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/urls/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/urls/_build_absolute_uri.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/models → djresttoolkit-1.2.1/src/djresttoolkit/views/_apiviews}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/_apiviews/_choice_fields_apiview.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/_exceptions/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/_exceptions/_exception_handler.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/views/mixins/_retrieve_object_mixin.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: djresttoolkit
|
3
|
-
Version: 1.1
|
3
|
+
Version: 1.2.1
|
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
|
@@ -970,7 +970,7 @@ from djresttoolkit.pagination import PaginatedDataBuilder
|
|
970
970
|
```python
|
971
971
|
builder = PaginatedDataBuilder(
|
972
972
|
request=request,
|
973
|
-
serializer_class=
|
973
|
+
serializer_class=BookSerializer,
|
974
974
|
queryset=MyModel.objects.all()
|
975
975
|
)
|
976
976
|
```
|
@@ -979,7 +979,7 @@ builder = PaginatedDataBuilder(
|
|
979
979
|
- `serializer_class: type[BaseSerializer]`:- DRF serializer class for the model.
|
980
980
|
- `queryset: QuerySet`:- Django queryset to paginate.
|
981
981
|
|
982
|
-
### Paginated Data Builder Methods
|
982
|
+
### Paginated Data Builder Methods and Property
|
983
983
|
|
984
984
|
- `get_paginated_data() -> dict[str, Any]`
|
985
985
|
|
@@ -987,6 +987,10 @@ builder = PaginatedDataBuilder(
|
|
987
987
|
- Serializes the paginated results.
|
988
988
|
- Returns a dictionary with `"page"` and `"results"`.
|
989
989
|
- Raises `NotFound` if no page data is found.
|
990
|
+
|
991
|
+
- `paginated_data -> dict[str, Any]`
|
992
|
+
|
993
|
+
- Call `paginated_data` property that internaly call `get_paginated_data()` method
|
990
994
|
|
991
995
|
### Example Response of Paginated Data Builder
|
992
996
|
|
@@ -1001,8 +1005,8 @@ builder = PaginatedDataBuilder(
|
|
1001
1005
|
"previous": "http://api.example.com/items/?page=1&page-size=20"
|
1002
1006
|
},
|
1003
1007
|
"results": [
|
1004
|
-
{ "id": 21, "
|
1005
|
-
{ "id": 22, "
|
1008
|
+
{ "id": 21, "title": "Title 21" },
|
1009
|
+
{ "id": 22, "title": "Title 22" }
|
1006
1010
|
]
|
1007
1011
|
}
|
1008
1012
|
```
|
@@ -1081,6 +1085,27 @@ class BookViewSet(CacheInvalidateMixin, ModelViewSet):
|
|
1081
1085
|
- Invalidates caches when books are created, updated, or deleted.
|
1082
1086
|
- Supports custom cache keys per action.
|
1083
1087
|
|
1088
|
+
### 17. EnhancedModelSerializer — API Reference
|
1089
|
+
|
1090
|
+
A subclass of Django REST Framework’s `ModelSerializer` that automatically merges Django model field `error_messages` into the serializer field, unless explicitly overridden.
|
1091
|
+
This helps maintain consistent validation messages between the model and the serializer.
|
1092
|
+
|
1093
|
+
#### Type Parameters
|
1094
|
+
|
1095
|
+
- `T` (`Model`): The Django model type that the serializer corresponds to.
|
1096
|
+
|
1097
|
+
#### Example of EnhancedModelSerializer
|
1098
|
+
|
1099
|
+
```python
|
1100
|
+
from myapp.models import Book
|
1101
|
+
from myapp.serializers import EnhancedModelSerializer
|
1102
|
+
|
1103
|
+
class BookSerializer(EnhancedModelSerializer[Book]):
|
1104
|
+
class Meta:
|
1105
|
+
model = Book
|
1106
|
+
fields = "__all__"
|
1107
|
+
```
|
1108
|
+
|
1084
1109
|
## 🛠️ Planned Features
|
1085
1110
|
|
1086
1111
|
- Add more utils
|
@@ -914,7 +914,7 @@ from djresttoolkit.pagination import PaginatedDataBuilder
|
|
914
914
|
```python
|
915
915
|
builder = PaginatedDataBuilder(
|
916
916
|
request=request,
|
917
|
-
serializer_class=
|
917
|
+
serializer_class=BookSerializer,
|
918
918
|
queryset=MyModel.objects.all()
|
919
919
|
)
|
920
920
|
```
|
@@ -923,7 +923,7 @@ builder = PaginatedDataBuilder(
|
|
923
923
|
- `serializer_class: type[BaseSerializer]`:- DRF serializer class for the model.
|
924
924
|
- `queryset: QuerySet`:- Django queryset to paginate.
|
925
925
|
|
926
|
-
### Paginated Data Builder Methods
|
926
|
+
### Paginated Data Builder Methods and Property
|
927
927
|
|
928
928
|
- `get_paginated_data() -> dict[str, Any]`
|
929
929
|
|
@@ -931,6 +931,10 @@ builder = PaginatedDataBuilder(
|
|
931
931
|
- Serializes the paginated results.
|
932
932
|
- Returns a dictionary with `"page"` and `"results"`.
|
933
933
|
- Raises `NotFound` if no page data is found.
|
934
|
+
|
935
|
+
- `paginated_data -> dict[str, Any]`
|
936
|
+
|
937
|
+
- Call `paginated_data` property that internaly call `get_paginated_data()` method
|
934
938
|
|
935
939
|
### Example Response of Paginated Data Builder
|
936
940
|
|
@@ -945,8 +949,8 @@ builder = PaginatedDataBuilder(
|
|
945
949
|
"previous": "http://api.example.com/items/?page=1&page-size=20"
|
946
950
|
},
|
947
951
|
"results": [
|
948
|
-
{ "id": 21, "
|
949
|
-
{ "id": 22, "
|
952
|
+
{ "id": 21, "title": "Title 21" },
|
953
|
+
{ "id": 22, "title": "Title 22" }
|
950
954
|
]
|
951
955
|
}
|
952
956
|
```
|
@@ -1025,6 +1029,27 @@ class BookViewSet(CacheInvalidateMixin, ModelViewSet):
|
|
1025
1029
|
- Invalidates caches when books are created, updated, or deleted.
|
1026
1030
|
- Supports custom cache keys per action.
|
1027
1031
|
|
1032
|
+
### 17. EnhancedModelSerializer — API Reference
|
1033
|
+
|
1034
|
+
A subclass of Django REST Framework’s `ModelSerializer` that automatically merges Django model field `error_messages` into the serializer field, unless explicitly overridden.
|
1035
|
+
This helps maintain consistent validation messages between the model and the serializer.
|
1036
|
+
|
1037
|
+
#### Type Parameters
|
1038
|
+
|
1039
|
+
- `T` (`Model`): The Django model type that the serializer corresponds to.
|
1040
|
+
|
1041
|
+
#### Example of EnhancedModelSerializer
|
1042
|
+
|
1043
|
+
```python
|
1044
|
+
from myapp.models import Book
|
1045
|
+
from myapp.serializers import EnhancedModelSerializer
|
1046
|
+
|
1047
|
+
class BookSerializer(EnhancedModelSerializer[Book]):
|
1048
|
+
class Meta:
|
1049
|
+
model = Book
|
1050
|
+
fields = "__all__"
|
1051
|
+
```
|
1052
|
+
|
1028
1053
|
## 🛠️ Planned Features
|
1029
1054
|
|
1030
1055
|
- Add more utils
|
@@ -57,8 +57,18 @@ class Todo(BaseModel):
|
|
57
57
|
on_delete=CASCADE,
|
58
58
|
related_name="todos",
|
59
59
|
help_text="Owner of this todo",
|
60
|
+
error_messages={
|
61
|
+
"null": "Every todo must belong to a user.",
|
62
|
+
"invalid": "Invalid user reference.",
|
63
|
+
},
|
64
|
+
)
|
65
|
+
title: CharField[str, str] = CharField(
|
66
|
+
max_length=255,
|
67
|
+
error_messages={
|
68
|
+
"blank": "Please give your todo a title.",
|
69
|
+
"max_length": "The title cannot exceed 255 characters.",
|
70
|
+
},
|
60
71
|
)
|
61
|
-
title: CharField[str, str] = CharField(max_length=255)
|
62
72
|
description: TextField[str, str] = TextField(blank=True, default="")
|
63
73
|
due_date: DateTimeField[str | None, str | None] = DateTimeField(
|
64
74
|
null=True,
|
@@ -69,16 +79,25 @@ class Todo(BaseModel):
|
|
69
79
|
max_length=20,
|
70
80
|
choices=TodoPriority.choices,
|
71
81
|
default=TodoPriority.MEDIUM,
|
82
|
+
error_messages={
|
83
|
+
"invalid_choice": "Priority must be one of: low, medium, high, critical.",
|
84
|
+
},
|
72
85
|
)
|
73
86
|
status: CharField[str, str] = CharField(
|
74
87
|
max_length=20,
|
75
88
|
choices=TodoStatus.choices,
|
76
89
|
default=TodoStatus.PENDING,
|
90
|
+
error_messages={
|
91
|
+
"invalid_choice": "Status must be one of: pending, in_progress, completed, archived.",
|
92
|
+
},
|
77
93
|
)
|
78
94
|
|
79
95
|
completed_at: DateTimeField[str | None, str | None] = DateTimeField(
|
80
96
|
null=True,
|
81
97
|
blank=True,
|
98
|
+
error_messages={
|
99
|
+
"invalid": "Completed at must be a valid datetime.",
|
100
|
+
},
|
82
101
|
)
|
83
102
|
|
84
103
|
def mark_completed(self) -> None:
|
@@ -4,8 +4,9 @@ URL configuration for todos app.
|
|
4
4
|
|
5
5
|
from django.urls import path
|
6
6
|
|
7
|
-
from .views import TodoDetailView
|
7
|
+
from .views import TodoDetailView, TodoListView
|
8
8
|
|
9
9
|
urlpatterns = [
|
10
|
+
path("", TodoListView.as_view(), name="todo-list"),
|
10
11
|
path("<int:id>/", TodoDetailView.as_view(), name="todo-detail"),
|
11
12
|
]
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from rest_framework.permissions import AllowAny
|
2
|
+
from rest_framework.request import Request
|
3
|
+
from rest_framework.response import Response
|
4
|
+
from rest_framework.views import APIView
|
5
|
+
|
6
|
+
from djresttoolkit.pagination import PaginatedDataBuilder
|
7
|
+
from djresttoolkit.views.mixins import RetrieveObjectMixin
|
8
|
+
|
9
|
+
from .models import Todo
|
10
|
+
from .serializers import TodoSerializer
|
11
|
+
|
12
|
+
|
13
|
+
class TodoListView(APIView):
|
14
|
+
permission_classes = [AllowAny]
|
15
|
+
|
16
|
+
def get(self, request: Request) -> Response:
|
17
|
+
pagination = PaginatedDataBuilder[Todo](
|
18
|
+
request=request,
|
19
|
+
serializer_class=TodoSerializer,
|
20
|
+
queryset=Todo.objects.all(),
|
21
|
+
)
|
22
|
+
return Response(data=pagination.paginated_data)
|
23
|
+
|
24
|
+
def post(self, request: Request) -> Response:
|
25
|
+
serializer = TodoSerializer(
|
26
|
+
data=request.data,
|
27
|
+
many=isinstance(request.data, list),
|
28
|
+
)
|
29
|
+
|
30
|
+
if serializer.is_valid():
|
31
|
+
serializer.save(user=request.user)
|
32
|
+
|
33
|
+
return Response(data=serializer.data)
|
34
|
+
|
35
|
+
|
36
|
+
class TodoDetailView(RetrieveObjectMixin[Todo], APIView):
|
37
|
+
permission_classes = [AllowAny]
|
38
|
+
queryset = Todo.objects.all()
|
39
|
+
|
40
|
+
def get(self, request: Request, id: int) -> Response:
|
41
|
+
todo = self.get_object(id=id)
|
42
|
+
serializer = TodoSerializer(instance=todo, many=False)
|
43
|
+
return Response(data=serializer.data)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
from os import getenv
|
2
3
|
from pathlib import Path
|
3
4
|
|
4
5
|
# Configuration Settings File for the django backend
|
@@ -12,7 +13,7 @@ sys.path.insert(0, str(SRC_DIR))
|
|
12
13
|
|
13
14
|
# Security Configuration Settings
|
14
15
|
# -------------------------------
|
15
|
-
SECRET_KEY = "
|
16
|
+
SECRET_KEY = getenv("SECRET_KEY")
|
16
17
|
|
17
18
|
# DEBUG Configuration Settings
|
18
19
|
# ----------------------------
|
@@ -164,6 +165,7 @@ MEDIA_URL = "/media/"
|
|
164
165
|
# -------------------------------------
|
165
166
|
REST_FRAMEWORK = {
|
166
167
|
"NON_FIELD_ERRORS_KEY": "non_field",
|
168
|
+
"DATETIME_FORMAT": "%Y-%m-%d %H:%M",
|
167
169
|
"DEFAULT_AUTHENTICATION_CLASSES": [
|
168
170
|
"rest_framework.authentication.TokenAuthentication",
|
169
171
|
],
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "djresttoolkit"
|
7
|
-
version = "1.1
|
7
|
+
version = "1.2.1"
|
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" }
|
@@ -45,10 +45,7 @@ keywords = [
|
|
45
45
|
"python-package",
|
46
46
|
]
|
47
47
|
requires-python = ">=3.13"
|
48
|
-
dependencies = [
|
49
|
-
"faker>=37.5.3",
|
50
|
-
"pydantic>=2.11.7",
|
51
|
-
]
|
48
|
+
dependencies = ["faker>=37.5.3", "pydantic>=2.11.7"]
|
52
49
|
|
53
50
|
# CLI scripts entry point configuration
|
54
51
|
# -------------------------------------
|
@@ -109,12 +106,19 @@ Source = "https://github.com/shaileshpandit141/djresttoolkit"
|
|
109
106
|
Issues = "https://github.com/shaileshpandit141/djresttoolkit/issues"
|
110
107
|
License = "https://github.com/shaileshpandit141/djresttoolkit/blob/main/LICENSE"
|
111
108
|
|
112
|
-
# ===================
|
113
|
-
# Tool Configurations
|
114
|
-
# ===================
|
115
109
|
|
110
|
+
# ==========================
|
111
|
+
# Add pyright Configurations
|
112
|
+
# ==========================
|
113
|
+
[tool.pyright]
|
114
|
+
typeCheckingMode = "strict"
|
115
|
+
reportMissingTypeStubs = false
|
116
|
+
reportUnknownMemberType = false
|
117
|
+
reportIncompatibleVariableOverride = false
|
118
|
+
|
119
|
+
# =========================================
|
116
120
|
# Disable ruff S101 rule for test casecases
|
117
|
-
#
|
121
|
+
# =========================================
|
118
122
|
[tool.ruff.lint.per-file-ignores]
|
119
123
|
"tests/*.py" = ["S101"]
|
120
124
|
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/src/djresttoolkit/pagination/_paginated_data_builder.py
RENAMED
@@ -1,11 +1,13 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Any
|
3
3
|
|
4
|
-
from django.db.models import QuerySet
|
4
|
+
from django.db.models import Model, QuerySet
|
5
5
|
from rest_framework.exceptions import NotFound
|
6
6
|
from rest_framework.request import Request
|
7
7
|
from rest_framework.serializers import BaseSerializer
|
8
|
-
|
8
|
+
|
9
|
+
from djresttoolkit.serializers import EnhancedModelSerializer
|
10
|
+
|
9
11
|
from ._page_number_pagination import PageNumberPagination
|
10
12
|
|
11
13
|
# Get logger from logging.
|
@@ -18,7 +20,7 @@ class PaginatedDataBuilder[T: Model]:
|
|
18
20
|
def __init__(
|
19
21
|
self,
|
20
22
|
request: Request,
|
21
|
-
serializer_class: type[BaseSerializer[T]],
|
23
|
+
serializer_class: type[BaseSerializer[T] | EnhancedModelSerializer[T]],
|
22
24
|
queryset: QuerySet[T],
|
23
25
|
) -> None:
|
24
26
|
"""Initilize the PaginatedDataBuilder class."""
|
@@ -49,7 +51,7 @@ class PaginatedDataBuilder[T: Model]:
|
|
49
51
|
)
|
50
52
|
|
51
53
|
# Construct the paginated response
|
52
|
-
paginated_data = {
|
54
|
+
paginated_data: dict[str, Any] = {
|
53
55
|
"page": {
|
54
56
|
"current": paginator.page.number, # type: ignore
|
55
57
|
"total": paginator.page.paginator.num_pages, # type: ignore
|
@@ -63,3 +65,7 @@ class PaginatedDataBuilder[T: Model]:
|
|
63
65
|
|
64
66
|
logger.debug(f"Pagination result: {paginated_data}")
|
65
67
|
return paginated_data
|
68
|
+
|
69
|
+
@property
|
70
|
+
def paginated_data(self) -> dict[str, Any]:
|
71
|
+
return self.get_paginated_data()
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from copy import deepcopy
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from django.db.models import Field as DjangoField
|
7
|
+
from django.db.models import Model
|
8
|
+
from rest_framework.serializers import Field as DrfField
|
9
|
+
from rest_framework.serializers import ModelSerializer
|
10
|
+
from rest_framework.utils.model_meta import RelationInfo
|
11
|
+
|
12
|
+
|
13
|
+
class EnhancedModelSerializer[T: Model](ModelSerializer[Model]):
|
14
|
+
"""
|
15
|
+
A DRF ModelSerializer that automatically applies Django model field
|
16
|
+
`error_messages` unless explicitly overridden in the serializer.
|
17
|
+
"""
|
18
|
+
|
19
|
+
def _merge_error_messages(
|
20
|
+
self,
|
21
|
+
field_kwargs: dict[str, Any],
|
22
|
+
model_field: DjangoField[Any, Any] | None,
|
23
|
+
) -> dict[str, Any]:
|
24
|
+
"""Safely merge model field error_messages with serializer kwargs."""
|
25
|
+
model_errors: dict[str, str] | None = getattr(
|
26
|
+
model_field, "error_messages", None
|
27
|
+
)
|
28
|
+
if model_errors:
|
29
|
+
existing: dict[str, str] = field_kwargs.get("error_messages", {})
|
30
|
+
field_kwargs["error_messages"] = {**deepcopy(model_errors), **existing}
|
31
|
+
return field_kwargs
|
32
|
+
|
33
|
+
def build_standard_field(
|
34
|
+
self,
|
35
|
+
field_name: str,
|
36
|
+
model_field: DjangoField[Any, Any],
|
37
|
+
) -> tuple[type[DrfField[Any, Any, Any, Any]], dict[str, Any]]:
|
38
|
+
field_class, field_kwargs = super().build_standard_field( # type: ignore
|
39
|
+
field_name,
|
40
|
+
model_field,
|
41
|
+
)
|
42
|
+
return field_class, self._merge_error_messages(
|
43
|
+
field_kwargs,
|
44
|
+
model_field,
|
45
|
+
) # type: ignore
|
46
|
+
|
47
|
+
def build_relational_field(
|
48
|
+
self,
|
49
|
+
field_name: str,
|
50
|
+
relation_info: RelationInfo,
|
51
|
+
) -> tuple[type[DrfField[Any, Any, Any, Any]], dict[str, Any]]:
|
52
|
+
field_class, field_kwargs = super().build_relational_field( # type: ignore
|
53
|
+
field_name,
|
54
|
+
relation_info,
|
55
|
+
)
|
56
|
+
return field_class, self._merge_error_messages(
|
57
|
+
field_kwargs,
|
58
|
+
relation_info.model_field, # type: ignore
|
59
|
+
)
|
@@ -1,18 +0,0 @@
|
|
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))
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/unusable_password_field.css
RENAMED
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/css/vendor/select2/select2.css
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/gis/move_vertex_off.svg
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/gis/move_vertex_on.svg
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/img/tooltag-arrowright.svg
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/admin/DateTimeShortcuts.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.1}/demo/staticfiles/admin/js/admin/RelatedObjectLookups.js
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|