djresttoolkit 1.1.0__tar.gz → 1.2.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-1.1.0 → djresttoolkit-1.2.0}/PKG-INFO +22 -1
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/README.md +21 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/models.py +20 -1
- djresttoolkit-1.2.0/demo/apps/todos/serializers.py +9 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/urls.py +2 -1
- djresttoolkit-1.2.0/demo/apps/todos/views.py +43 -0
- djresttoolkit-1.2.0/demo/apps_config/__init__.py +3 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/settings.py +3 -1
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/pyproject.toml +13 -9
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/pagination/_paginated_data_builder.py +6 -4
- djresttoolkit-1.2.0/src/djresttoolkit/serializers/__init__.py +3 -0
- djresttoolkit-1.2.0/src/djresttoolkit/serializers/_enhanced_model_serializer.py +59 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/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.0}/.gitignore +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/.python-version +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/.vscode/settings.json +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/LICENSE +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/admin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/apps.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/dbseed/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/dbseed/tag_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/dbseed/todo_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/dbseed/todo_tag_seed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/migrations/0001_initial.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/migrations/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps/todos/tests.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/asgi.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/serializers.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/urls.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/views.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/apps_config/wsgi.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/manage.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/autocomplete.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/base.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/changelists.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/dark_mode.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/dashboard.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/forms.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/login.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/nav_sidebar.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/responsive.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/responsive_rtl.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/rtl.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/unusable_password_field.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/vendor/select2/select2.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/vendor/select2/select2.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/css/widgets.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/LICENSE +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/README.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/calendar-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/gis/move_vertex_off.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/gis/move_vertex_on.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-addlink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-alert.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-calendar.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-changelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-clock.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-deletelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-hidelink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-no.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-unknown-alt.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-unknown.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-viewlink.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/icon-yes.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/inline-delete.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/search.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/selector-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/sorting-icons.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/tooltag-add.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/img/tooltag-arrowright.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/SelectBox.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/SelectFilter2.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/actions.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/admin/DateTimeShortcuts.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/admin/RelatedObjectLookups.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/autocomplete.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/calendar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/cancel.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/change_form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/core.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/filters.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/inlines.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/jquery.init.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/nav_sidebar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/popup_response.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/prepopulate.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/prepopulate_init.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/theme.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/unusable_password_field.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/urlify.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/LICENSE.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/LICENSE.md +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/af.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ar.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/az.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bg.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bn.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bs.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ca.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/cs.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/da.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/de.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/dsb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/el.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/en.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/es.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/et.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/eu.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fa.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/fr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/gl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/he.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hsb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hu.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/hy.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/id.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/is.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/it.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ja.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ka.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/km.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ko.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/lt.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/lv.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/mk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ms.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/nb.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ne.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/nl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ps.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pt-BR.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/pt.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ro.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ru.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sq.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sr-Cyrl.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/sv.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/th.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/tk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/tr.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/uk.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/vi.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-CN.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/zh-TW.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/select2.full.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/select2.full.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/xregexp/LICENSE.txt +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/xregexp/xregexp.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/bootstrap-theme.min.css.map +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/bootstrap-tweaks.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/bootstrap.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/bootstrap.min.css.map +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/default.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/font-awesome-4.0.3.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/css/prettify.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/css/base.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/css/highlight.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/css/jquery.json-view.min.css +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/img/favicon.ico +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/img/grid.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/js/api.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/js/highlight.pack.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/docs/js/jquery.json-view.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.eot +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.ttf +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/fontawesome-webfont.woff +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.eot +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.svg +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.ttf +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/img/glyphicons-halflings-white.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/img/glyphicons-halflings.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/img/grid.png +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/ajax-form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/bootstrap.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/coreapi-0.1.1.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/csrf.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/default.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/jquery-3.7.1.min.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/load-ajax-form.js +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/rest_framework/js/prettify-min.js +0 -0
- {djresttoolkit-1.1.0/demo/apps_config → djresttoolkit-1.2.0/src/djresttoolkit}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/admin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/apps.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit → djresttoolkit-1.2.0/src/djresttoolkit/cache}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/_cache_action_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/_cache_invalidate_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/_cache_key_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/_cache_list_retrieve_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/cache/mixins/_cache_ops_mixin.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/cache → djresttoolkit-1.2.0/src/djresttoolkit/dbseed}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/dbseed/models/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/dbseed/models/_choice_field.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/dbseed/models/_gen.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/dbseed/models/_seed_model.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/envconfig/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/envconfig/_base_env_config.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/mail/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/mail/_email_sender.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/mail/_models.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/mail/_types.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/dbseed → djresttoolkit-1.2.0/src/djresttoolkit/management}/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/management → djresttoolkit-1.2.0/src/djresttoolkit/management/commands}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/management/commands/dbflush.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/management/commands/dbseed.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/middlewares/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/middlewares/_response_time_middleware.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/management/commands → djresttoolkit-1.2.0/src/djresttoolkit/migrations}/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/migrations → djresttoolkit-1.2.0/src/djresttoolkit/models}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/models/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/models/mixins/_model_choice_fields_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/pagination/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/pagination/_page_number_pagination.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/py.typed +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/renderers/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/renderers/_throttle_info_json_renderer.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/serializers/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/serializers/mixins/_absolute_url_file_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/serializers/mixins/_bulk_create_mixin.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/throttling/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/throttling/_throttle_inspector.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/urls/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/urls/_build_absolute_uri.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/views/__init__.py +0 -0
- {djresttoolkit-1.1.0/src/djresttoolkit/models → djresttoolkit-1.2.0/src/djresttoolkit/views/_apiviews}/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/views/_apiviews/_choice_fields_apiview.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/views/_exceptions/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/views/_exceptions/_exception_handler.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/src/djresttoolkit/views/mixins/__init__.py +0 -0
- {djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/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.
|
3
|
+
Version: 1.2.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
|
@@ -1081,6 +1081,27 @@ class BookViewSet(CacheInvalidateMixin, ModelViewSet):
|
|
1081
1081
|
- Invalidates caches when books are created, updated, or deleted.
|
1082
1082
|
- Supports custom cache keys per action.
|
1083
1083
|
|
1084
|
+
### 17. EnhancedModelSerializer — API Reference
|
1085
|
+
|
1086
|
+
A subclass of Django REST Framework’s `ModelSerializer` that automatically merges Django model field `error_messages` into the serializer field, unless explicitly overridden.
|
1087
|
+
This helps maintain consistent validation messages between the model and the serializer.
|
1088
|
+
|
1089
|
+
#### Type Parameters
|
1090
|
+
|
1091
|
+
- `T` (`Model`): The Django model type that the serializer corresponds to.
|
1092
|
+
|
1093
|
+
#### Example of EnhancedModelSerializer
|
1094
|
+
|
1095
|
+
```python
|
1096
|
+
from myapp.models import Book
|
1097
|
+
from myapp.serializers import EnhancedModelSerializer
|
1098
|
+
|
1099
|
+
class BookSerializer(EnhancedModelSerializer[Book]):
|
1100
|
+
class Meta:
|
1101
|
+
model = Book
|
1102
|
+
fields = "__all__"
|
1103
|
+
```
|
1104
|
+
|
1084
1105
|
## 🛠️ Planned Features
|
1085
1106
|
|
1086
1107
|
- Add more utils
|
@@ -1025,6 +1025,27 @@ class BookViewSet(CacheInvalidateMixin, ModelViewSet):
|
|
1025
1025
|
- Invalidates caches when books are created, updated, or deleted.
|
1026
1026
|
- Supports custom cache keys per action.
|
1027
1027
|
|
1028
|
+
### 17. EnhancedModelSerializer — API Reference
|
1029
|
+
|
1030
|
+
A subclass of Django REST Framework’s `ModelSerializer` that automatically merges Django model field `error_messages` into the serializer field, unless explicitly overridden.
|
1031
|
+
This helps maintain consistent validation messages between the model and the serializer.
|
1032
|
+
|
1033
|
+
#### Type Parameters
|
1034
|
+
|
1035
|
+
- `T` (`Model`): The Django model type that the serializer corresponds to.
|
1036
|
+
|
1037
|
+
#### Example of EnhancedModelSerializer
|
1038
|
+
|
1039
|
+
```python
|
1040
|
+
from myapp.models import Book
|
1041
|
+
from myapp.serializers import EnhancedModelSerializer
|
1042
|
+
|
1043
|
+
class BookSerializer(EnhancedModelSerializer[Book]):
|
1044
|
+
class Meta:
|
1045
|
+
model = Book
|
1046
|
+
fields = "__all__"
|
1047
|
+
```
|
1048
|
+
|
1028
1049
|
## 🛠️ Planned Features
|
1029
1050
|
|
1030
1051
|
- 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.get_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.
|
7
|
+
version = "1.2.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" }
|
@@ -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.0}/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
|
@@ -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.0}/demo/staticfiles/admin/css/unusable_password_field.css
RENAMED
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/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.0}/demo/staticfiles/admin/img/gis/move_vertex_off.svg
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/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.0}/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.0}/demo/staticfiles/admin/js/admin/DateTimeShortcuts.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/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
|
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.0}/demo/staticfiles/admin/js/unusable_password_field.js
RENAMED
File without changes
|
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/LICENSE.txt
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/jquery/jquery.min.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/LICENSE.md
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/af.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ar.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/az.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bg.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bn.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/bs.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/ca.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/cs.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/da.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/de.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/dsb.js
RENAMED
File without changes
|
{djresttoolkit-1.1.0 → djresttoolkit-1.2.0}/demo/staticfiles/admin/js/vendor/select2/i18n/el.js
RENAMED
File without changes
|