djcrud 0.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.
- djcrud-0.2.0/.github/workflows/ci.yml +45 -0
- djcrud-0.2.0/.github/workflows/docs.yml +53 -0
- djcrud-0.2.0/.github/workflows/install-test.yml +81 -0
- djcrud-0.2.0/.github/workflows/release.yml +70 -0
- djcrud-0.2.0/.gitignore +10 -0
- djcrud-0.2.0/CLAUDE.md +282 -0
- djcrud-0.2.0/PKG-INFO +111 -0
- djcrud-0.2.0/README.md +67 -0
- djcrud-0.2.0/docs/Makefile +15 -0
- djcrud-0.2.0/docs/_static/.gitkeep +0 -0
- djcrud-0.2.0/docs/_static/screenshots/article-detail.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/article-list.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/bulk-delete-modal.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/item-list.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/list-action-bar.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/set-category-modal.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/site-search.png +0 -0
- djcrud-0.2.0/docs/_static/screenshots/success-toast.png +0 -0
- djcrud-0.2.0/docs/conf.py +84 -0
- djcrud-0.2.0/docs/contributing.rst +355 -0
- djcrud-0.2.0/docs/demo.rst +98 -0
- djcrud-0.2.0/docs/index.rst +23 -0
- djcrud-0.2.0/docs/install.rst +133 -0
- djcrud-0.2.0/docs/philosophy.rst +167 -0
- djcrud-0.2.0/docs/reference/clonable.rst +6 -0
- djcrud-0.2.0/docs/reference/djcrud_api/index.rst +223 -0
- djcrud-0.2.0/docs/reference/djcrud_auth/index.rst +6 -0
- djcrud-0.2.0/docs/reference/djcrud_dal/index.rst +14 -0
- djcrud-0.2.0/docs/reference/djcrud_dal_topbar/index.rst +19 -0
- djcrud-0.2.0/docs/reference/djcrud_debug/index.rst +6 -0
- djcrud-0.2.0/docs/reference/djcrud_history/index.rst +6 -0
- djcrud-0.2.0/docs/reference/index.rst +22 -0
- djcrud-0.2.0/docs/reference/mixins/action.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/delete.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/filter.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/form.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/index.rst +28 -0
- djcrud-0.2.0/docs/reference/mixins/list.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/list_action.rst +7 -0
- djcrud-0.2.0/docs/reference/mixins/log.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/modelform.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/object.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/object_modelform.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/objectform.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/pagination.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/tables2.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/template.rst +6 -0
- djcrud-0.2.0/docs/reference/mixins/template_view.rst +6 -0
- djcrud-0.2.0/docs/reference/model.rst +6 -0
- djcrud-0.2.0/docs/reference/registry.rst +6 -0
- djcrud-0.2.0/docs/reference/route.rst +6 -0
- djcrud-0.2.0/docs/reference/router.rst +6 -0
- djcrud-0.2.0/docs/reference/site.rst +22 -0
- djcrud-0.2.0/docs/reference/templatetags.rst +16 -0
- djcrud-0.2.0/docs/reference/view.rst +10 -0
- djcrud-0.2.0/docs/reference/views/create.rst +6 -0
- djcrud-0.2.0/docs/reference/views/delete.rst +13 -0
- djcrud-0.2.0/docs/reference/views/detail.rst +6 -0
- djcrud-0.2.0/docs/reference/views/form.rst +6 -0
- djcrud-0.2.0/docs/reference/views/index.rst +16 -0
- djcrud-0.2.0/docs/reference/views/list.rst +13 -0
- djcrud-0.2.0/docs/reference/views/list_action.rst +6 -0
- djcrud-0.2.0/docs/reference/views/template.rst +13 -0
- djcrud-0.2.0/docs/reference/views/update.rst +6 -0
- djcrud-0.2.0/docs/requirements.txt +3 -0
- djcrud-0.2.0/docs/tutorial/index.rst +20 -0
- djcrud-0.2.0/docs/tutorial/stage0.rst +89 -0
- djcrud-0.2.0/docs/tutorial/stage1.rst +48 -0
- djcrud-0.2.0/docs/tutorial/stage2.rst +35 -0
- djcrud-0.2.0/docs/tutorial/stage3.rst +56 -0
- djcrud-0.2.0/docs/tutorial/stage4.rst +61 -0
- djcrud-0.2.0/docs/tutorial/stage5.rst +100 -0
- djcrud-0.2.0/manage.py +23 -0
- djcrud-0.2.0/package-lock.json +1493 -0
- djcrud-0.2.0/package.json +14 -0
- djcrud-0.2.0/pyproject.toml +113 -0
- djcrud-0.2.0/setup.cfg +4 -0
- djcrud-0.2.0/src/djcrud/__init__.py +145 -0
- djcrud-0.2.0/src/djcrud/admin.py +3 -0
- djcrud-0.2.0/src/djcrud/apps.py +5 -0
- djcrud-0.2.0/src/djcrud/backends.py +159 -0
- djcrud-0.2.0/src/djcrud/clonable.py +15 -0
- djcrud-0.2.0/src/djcrud/errors.py +81 -0
- djcrud-0.2.0/src/djcrud/handlers.py +23 -0
- djcrud-0.2.0/src/djcrud/introspection.py +95 -0
- djcrud-0.2.0/src/djcrud/locale/en/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud/locale/en/LC_MESSAGES/django.po +150 -0
- djcrud-0.2.0/src/djcrud/locale/fr/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud/locale/fr/LC_MESSAGES/django.po +150 -0
- djcrud-0.2.0/src/djcrud/management/commands/show_urls.py +218 -0
- djcrud-0.2.0/src/djcrud/model.py +70 -0
- djcrud-0.2.0/src/djcrud/models.py +3 -0
- djcrud-0.2.0/src/djcrud/redirect.py +39 -0
- djcrud-0.2.0/src/djcrud/registry.py +54 -0
- djcrud-0.2.0/src/djcrud/route.py +56 -0
- djcrud-0.2.0/src/djcrud/router.py +132 -0
- djcrud-0.2.0/src/djcrud/settings.py +16 -0
- djcrud-0.2.0/src/djcrud/templatetags/djcrud.py +199 -0
- djcrud-0.2.0/src/djcrud/tests.py +3 -0
- djcrud-0.2.0/src/djcrud/view.py +236 -0
- djcrud-0.2.0/src/djcrud/views/action.py +18 -0
- djcrud-0.2.0/src/djcrud/views/create.py +49 -0
- djcrud-0.2.0/src/djcrud/views/delete.py +250 -0
- djcrud-0.2.0/src/djcrud/views/detail.py +115 -0
- djcrud-0.2.0/src/djcrud/views/filter.py +141 -0
- djcrud-0.2.0/src/djcrud/views/form.py +95 -0
- djcrud-0.2.0/src/djcrud/views/generic.py +17 -0
- djcrud-0.2.0/src/djcrud/views/json.py +146 -0
- djcrud-0.2.0/src/djcrud/views/list.py +290 -0
- djcrud-0.2.0/src/djcrud/views/list_action.py +71 -0
- djcrud-0.2.0/src/djcrud/views/log.py +190 -0
- djcrud-0.2.0/src/djcrud/views/modelform.py +37 -0
- djcrud-0.2.0/src/djcrud/views/object.py +78 -0
- djcrud-0.2.0/src/djcrud/views/objectform.py +31 -0
- djcrud-0.2.0/src/djcrud/views/pagination.py +136 -0
- djcrud-0.2.0/src/djcrud/views/search.py +54 -0
- djcrud-0.2.0/src/djcrud/views/swagger.py +64 -0
- djcrud-0.2.0/src/djcrud/views/tables2.py +228 -0
- djcrud-0.2.0/src/djcrud/views/template.py +62 -0
- djcrud-0.2.0/src/djcrud/views/update.py +54 -0
- djcrud-0.2.0/src/djcrud.egg-info/PKG-INFO +111 -0
- djcrud-0.2.0/src/djcrud.egg-info/SOURCES.txt +344 -0
- djcrud-0.2.0/src/djcrud.egg-info/dependency_links.txt +1 -0
- djcrud-0.2.0/src/djcrud.egg-info/requires.txt +30 -0
- djcrud-0.2.0/src/djcrud.egg-info/scm_file_list.json +341 -0
- djcrud-0.2.0/src/djcrud.egg-info/scm_version.json +8 -0
- djcrud-0.2.0/src/djcrud.egg-info/top_level.txt +10 -0
- djcrud-0.2.0/src/djcrud_api/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_api/apps.py +10 -0
- djcrud-0.2.0/src/djcrud_api/djcrud.py +5 -0
- djcrud-0.2.0/src/djcrud_api/middleware.py +53 -0
- djcrud-0.2.0/src/djcrud_api/migrations/0001_initial.py +50 -0
- djcrud-0.2.0/src/djcrud_api/migrations/0002_rename_from_djmvc_swagger.py +24 -0
- djcrud-0.2.0/src/djcrud_api/migrations/0003_rename_from_djmvc_api.py +37 -0
- djcrud-0.2.0/src/djcrud_api/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_api/models.py +71 -0
- djcrud-0.2.0/src/djcrud_api/static/djcrud_api/swagger-ui-bundle.js +3 -0
- djcrud-0.2.0/src/djcrud_api/static/djcrud_api/swagger-ui-standalone-preset.js +3 -0
- djcrud-0.2.0/src/djcrud_api/static/djcrud_api/swagger-ui.css +4 -0
- djcrud-0.2.0/src/djcrud_api/templates/djcrud_api/api.html +54 -0
- djcrud-0.2.0/src/djcrud_api/views.py +239 -0
- djcrud-0.2.0/src/djcrud_auth/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_auth/admin.py +3 -0
- djcrud-0.2.0/src/djcrud_auth/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_auth/djcrud.py +8 -0
- djcrud-0.2.0/src/djcrud_auth/locale/en/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud_auth/locale/en/LC_MESSAGES/django.po +75 -0
- djcrud-0.2.0/src/djcrud_auth/locale/fr/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud_auth/locale/fr/LC_MESSAGES/django.po +75 -0
- djcrud-0.2.0/src/djcrud_auth/models.py +3 -0
- djcrud-0.2.0/src/djcrud_auth/tests.py +3 -0
- djcrud-0.2.0/src/djcrud_auth/views.py +312 -0
- djcrud-0.2.0/src/djcrud_bulma/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_bulma/admin.py +3 -0
- djcrud-0.2.0/src/djcrud_bulma/apps.py +14 -0
- djcrud-0.2.0/src/djcrud_bulma/locale/en/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud_bulma/locale/en/LC_MESSAGES/django.po +123 -0
- djcrud-0.2.0/src/djcrud_bulma/locale/fr/LC_MESSAGES/django.mo +0 -0
- djcrud-0.2.0/src/djcrud_bulma/locale/fr/LC_MESSAGES/django.po +123 -0
- djcrud-0.2.0/src/djcrud_bulma/models.py +3 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/css/style.css +259 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/filter-sidebar.js +121 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/filter-sidebar.test.js +147 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/form-focus.js +45 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/form-focus.test.js +93 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/hamburger.js +73 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/hamburger.test.js +208 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/list-action-bar.js +278 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/list-action-bar.test.js +187 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/nav-config.js +9 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/nav-config.test.js +32 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/toast.js +19 -0
- djcrud-0.2.0/src/djcrud_bulma/static/djcrud_bulma/js/toast.test.js +89 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/400.html +1 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/403.html +1 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/404.html +1 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/500.html +1 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_actions_column.html +40 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_checkbox_column.html +3 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_checkbox_header.html +3 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_deletion_preview.html +29 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_error.html +6 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_filter.html +26 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_flashes.html +15 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_navbar_burger.html +6 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_object_list.html +21 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_pagination.html +83 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/_tables2.html +81 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/base.html +111 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/base_immersive.html +9 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/detail.html +46 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/detaillist.html +69 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/error.html +7 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/form.html +74 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/form_delete.html +40 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/home.html +32 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/list.html +67 -0
- djcrud-0.2.0/src/djcrud_bulma/templates/djcrud/test_immersive.html +3 -0
- djcrud-0.2.0/src/djcrud_bulma/tests.py +3 -0
- djcrud-0.2.0/src/djcrud_bulma/views.py +3 -0
- djcrud-0.2.0/src/djcrud_dal/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_dal/apps.py +26 -0
- djcrud-0.2.0/src/djcrud_dal/hooks.py +62 -0
- djcrud-0.2.0/src/djcrud_dal/lookup.py +23 -0
- djcrud-0.2.0/src/djcrud_dal/models.py +5 -0
- djcrud-0.2.0/src/djcrud_dal/views.py +31 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/apps.py +20 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/djcrud.py +5 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/lookup.py +87 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/static/djcrud_dal_topbar/css/site-search.css +27 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/static/djcrud_dal_topbar/js/site-search.js +6 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/templates/djcrud/_site_search.html +17 -0
- djcrud-0.2.0/src/djcrud_dal_topbar/views.py +75 -0
- djcrud-0.2.0/src/djcrud_debug/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_debug/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_debug/djcrud.py +5 -0
- djcrud-0.2.0/src/djcrud_debug/models.py +56 -0
- djcrud-0.2.0/src/djcrud_debug/routing_debug.py +160 -0
- djcrud-0.2.0/src/djcrud_debug/views.py +44 -0
- djcrud-0.2.0/src/djcrud_example/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/asgi.py +16 -0
- djcrud-0.2.0/src/djcrud_example/example_urls.py +35 -0
- djcrud-0.2.0/src/djcrud_example/migrations/0001_initial.py +132 -0
- djcrud-0.2.0/src/djcrud_example/migrations/0002_test_users.py +27 -0
- djcrud-0.2.0/src/djcrud_example/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/models.py +5 -0
- djcrud-0.2.0/src/djcrud_example/settings.py +164 -0
- djcrud-0.2.0/src/djcrud_example/stage0/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage0/admin.py +3 -0
- djcrud-0.2.0/src/djcrud_example/stage0/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage0/djcrud.py +14 -0
- djcrud-0.2.0/src/djcrud_example/stage0/migrations/0001_initial.py +26 -0
- djcrud-0.2.0/src/djcrud_example/stage0/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage0/models.py +8 -0
- djcrud-0.2.0/src/djcrud_example/stage0/tests.py +3 -0
- djcrud-0.2.0/src/djcrud_example/stage1/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage1/admin.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage1/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage1/djcrud.py +22 -0
- djcrud-0.2.0/src/djcrud_example/stage1/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage1/models.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage1/tests.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage2/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage2/admin.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage2/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage2/djcrud.py +18 -0
- djcrud-0.2.0/src/djcrud_example/stage2/migrations/0001_initial.py +40 -0
- djcrud-0.2.0/src/djcrud_example/stage2/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage2/models.py +14 -0
- djcrud-0.2.0/src/djcrud_example/stage2/tests.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage3/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage3/admin.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage3/apps.py +6 -0
- djcrud-0.2.0/src/djcrud_example/stage3/backends.py +35 -0
- djcrud-0.2.0/src/djcrud_example/stage3/djcrud.py +28 -0
- djcrud-0.2.0/src/djcrud_example/stage3/migrations/0001_initial.py +44 -0
- djcrud-0.2.0/src/djcrud_example/stage3/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage3/models.py +21 -0
- djcrud-0.2.0/src/djcrud_example/stage3/tests.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage4/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage4/admin.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage4/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage4/djcrud.py +29 -0
- djcrud-0.2.0/src/djcrud_example/stage4/migrations/0001_initial.py +30 -0
- djcrud-0.2.0/src/djcrud_example/stage4/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage4/models.py +10 -0
- djcrud-0.2.0/src/djcrud_example/stage4/tests.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage5/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage5/admin.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage5/apps.py +5 -0
- djcrud-0.2.0/src/djcrud_example/stage5/djcrud.py +45 -0
- djcrud-0.2.0/src/djcrud_example/stage5/migrations/0001_initial.py +29 -0
- djcrud-0.2.0/src/djcrud_example/stage5/migrations/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_example/stage5/models.py +9 -0
- djcrud-0.2.0/src/djcrud_example/stage5/tests.py +0 -0
- djcrud-0.2.0/src/djcrud_example/urls.py +13 -0
- djcrud-0.2.0/src/djcrud_example/wsgi.py +16 -0
- djcrud-0.2.0/src/djcrud_history/__init__.py +0 -0
- djcrud-0.2.0/src/djcrud_history/apps.py +15 -0
- djcrud-0.2.0/src/djcrud_history/djcrud.py +5 -0
- djcrud-0.2.0/src/djcrud_history/log.py +21 -0
- djcrud-0.2.0/src/djcrud_history/models.py +5 -0
- djcrud-0.2.0/src/djcrud_history/views.py +76 -0
- djcrud-0.2.0/src/djcrud_triggers/__init__.py +1 -0
- djcrud-0.2.0/src/djcrud_triggers/apps.py +22 -0
- djcrud-0.2.0/src/djcrud_triggers/hooks/__init__.py +12 -0
- djcrud-0.2.0/src/djcrud_triggers/hooks/events.py +40 -0
- djcrud-0.2.0/src/djcrud_triggers/hooks/registry.py +135 -0
- djcrud-0.2.0/src/djcrud_triggers/hooks/runner.py +52 -0
- djcrud-0.2.0/tests/alight_helpers.py +164 -0
- djcrud-0.2.0/tests/conftest.py +54 -0
- djcrud-0.2.0/tests/dal_screenshots.py +17 -0
- djcrud-0.2.0/tests/doc_screenshots.py +42 -0
- djcrud-0.2.0/tests/screenshots/dal/user-list-filter-groups-filtered.png +0 -0
- djcrud-0.2.0/tests/screenshots/dal/user-list-filter-groups-initial.png +0 -0
- djcrud-0.2.0/tests/screenshots/dal/user-list-filter-groups-selected.png +0 -0
- djcrud-0.2.0/tests/screenshots/dal/user-update-groups-initial.png +0 -0
- djcrud-0.2.0/tests/screenshots/dal/user-update-groups-selected.png +0 -0
- djcrud-0.2.0/tests/screenshots/topbar/site-search-detail.png +0 -0
- djcrud-0.2.0/tests/screenshots/topbar/site-search-initial.png +0 -0
- djcrud-0.2.0/tests/screenshots/topbar/site-search-results.png +0 -0
- djcrud-0.2.0/tests/test_api.py +124 -0
- djcrud-0.2.0/tests/test_auth.py +251 -0
- djcrud-0.2.0/tests/test_breadcrumbs.py +177 -0
- djcrud-0.2.0/tests/test_detail_list.py +37 -0
- djcrud-0.2.0/tests/test_djcrud_dal.py +98 -0
- djcrud-0.2.0/tests/test_djcrud_dal_splinter.py +133 -0
- djcrud-0.2.0/tests/test_djcrud_dal_topbar.py +97 -0
- djcrud-0.2.0/tests/test_djcrud_dal_topbar_splinter.py +75 -0
- djcrud-0.2.0/tests/test_djcrud_tags.py +109 -0
- djcrud-0.2.0/tests/test_djcrud_triggers.py +53 -0
- djcrud-0.2.0/tests/test_docs_screenshots.py +113 -0
- djcrud-0.2.0/tests/test_errors.py +106 -0
- djcrud-0.2.0/tests/test_eval.py +16 -0
- djcrud-0.2.0/tests/test_filter.py +379 -0
- djcrud-0.2.0/tests/test_form_focus.py +75 -0
- djcrud-0.2.0/tests/test_hamburger.py +84 -0
- djcrud-0.2.0/tests/test_i18n.py +44 -0
- djcrud-0.2.0/tests/test_immersive.py +186 -0
- djcrud-0.2.0/tests/test_list_action.py +428 -0
- djcrud-0.2.0/tests/test_list_combinations.py +206 -0
- djcrud-0.2.0/tests/test_logentry.py +284 -0
- djcrud-0.2.0/tests/test_messages.py +162 -0
- djcrud-0.2.0/tests/test_messages_browser.py +108 -0
- djcrud-0.2.0/tests/test_nav_active.py +87 -0
- djcrud-0.2.0/tests/test_pagination.py +229 -0
- djcrud-0.2.0/tests/test_permissions.py +240 -0
- djcrud-0.2.0/tests/test_queryset.py +86 -0
- djcrud-0.2.0/tests/test_registry.py +105 -0
- djcrud-0.2.0/tests/test_router.py +74 -0
- djcrud-0.2.0/tests/test_routing.py +46 -0
- djcrud-0.2.0/tests/test_routing_debug.py +94 -0
- djcrud-0.2.0/tests/test_stage0.py +72 -0
- djcrud-0.2.0/tests/test_stage1.py +43 -0
- djcrud-0.2.0/tests/test_stage2.py +86 -0
- djcrud-0.2.0/tests/test_stage3.py +61 -0
- djcrud-0.2.0/tests/test_stage4.py +65 -0
- djcrud-0.2.0/tests/test_stage5.py +48 -0
- djcrud-0.2.0/tests/test_tokens.py +198 -0
- djcrud-0.2.0/tests/test_tutorial_docs.py +31 -0
- djcrud-0.2.0/tests/test_view.py +54 -0
- djcrud-0.2.0/tests/topbar_screenshots.py +17 -0
- djcrud-0.2.0/tests/views/test_template.py +19 -0
- djcrud-0.2.0/tox.ini +14 -0
- djcrud-0.2.0/vitest.config.js +15 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test-python:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.x"
|
|
16
|
+
|
|
17
|
+
- uses: browser-actions/setup-firefox@latest
|
|
18
|
+
- uses: browser-actions/setup-geckodriver@latest
|
|
19
|
+
with:
|
|
20
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
21
|
+
|
|
22
|
+
- name: Install package and test dependencies
|
|
23
|
+
run: |
|
|
24
|
+
pip install -U pip
|
|
25
|
+
pip install -U django
|
|
26
|
+
pip install --pre -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
- name: Run unit and integration tests
|
|
29
|
+
run: pytest -m "not splinter" -n auto
|
|
30
|
+
|
|
31
|
+
- name: Run browser tests
|
|
32
|
+
run: pytest -m splinter -n 0 --splinter-headless
|
|
33
|
+
|
|
34
|
+
test-js:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- uses: actions/setup-node@v4
|
|
40
|
+
with:
|
|
41
|
+
node-version: "20"
|
|
42
|
+
cache: npm
|
|
43
|
+
|
|
44
|
+
- run: npm ci
|
|
45
|
+
- run: npm test
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: pages
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
|
|
28
|
+
- name: Install package and doc dependencies
|
|
29
|
+
run: pip install --pre -e ".[dev,docs]" -r docs/requirements.txt
|
|
30
|
+
|
|
31
|
+
- name: Validate tutorial example apps
|
|
32
|
+
run: pytest -m tutorial -n 0
|
|
33
|
+
|
|
34
|
+
- name: Build Sphinx HTML
|
|
35
|
+
run: make -C docs html
|
|
36
|
+
|
|
37
|
+
- name: Upload Pages artifact
|
|
38
|
+
if: github.event_name != 'pull_request'
|
|
39
|
+
uses: actions/upload-pages-artifact@v3
|
|
40
|
+
with:
|
|
41
|
+
path: docs/_build/html
|
|
42
|
+
|
|
43
|
+
deploy:
|
|
44
|
+
if: github.event_name != 'pull_request'
|
|
45
|
+
needs: build
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
environment:
|
|
48
|
+
name: github-pages
|
|
49
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
50
|
+
steps:
|
|
51
|
+
- name: Deploy to GitHub Pages
|
|
52
|
+
id: deployment
|
|
53
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Installation Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test-install:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.x"
|
|
16
|
+
|
|
17
|
+
- name: Install djcrud
|
|
18
|
+
run: |
|
|
19
|
+
pip install -U pip
|
|
20
|
+
pip install --pre .
|
|
21
|
+
|
|
22
|
+
- name: Create test Django project
|
|
23
|
+
run: |
|
|
24
|
+
mkdir -p /tmp/djcrud-test
|
|
25
|
+
cd /tmp/djcrud-test
|
|
26
|
+
django-admin startproject testproject
|
|
27
|
+
cd testproject
|
|
28
|
+
|
|
29
|
+
- name: Configure settings
|
|
30
|
+
run: |
|
|
31
|
+
cd /tmp/djcrud-test/testproject
|
|
32
|
+
cat >> testproject/settings.py << 'EOF'
|
|
33
|
+
|
|
34
|
+
# djcrud configuration
|
|
35
|
+
import djcrud.settings
|
|
36
|
+
|
|
37
|
+
INSTALLED_APPS = djcrud.settings.INSTALLED_APPS + [
|
|
38
|
+
"django.contrib.admin",
|
|
39
|
+
"django.contrib.auth",
|
|
40
|
+
"django.contrib.contenttypes",
|
|
41
|
+
"django.contrib.sessions",
|
|
42
|
+
"django.contrib.messages",
|
|
43
|
+
"django.contrib.staticfiles",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
MIDDLEWARE = [
|
|
47
|
+
"django.middleware.security.SecurityMiddleware",
|
|
48
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
49
|
+
"djcrud_api.middleware.BearerCsrfMiddleware",
|
|
50
|
+
"django.middleware.locale.LocaleMiddleware",
|
|
51
|
+
"django.middleware.common.CommonMiddleware",
|
|
52
|
+
"django.middleware.csrf.CsrfViewMiddleware",
|
|
53
|
+
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
54
|
+
"djcrud_api.middleware.BearerUserMiddleware",
|
|
55
|
+
"django.contrib.messages.middleware.MessageMiddleware",
|
|
56
|
+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
57
|
+
]
|
|
58
|
+
EOF
|
|
59
|
+
|
|
60
|
+
- name: Configure URLs
|
|
61
|
+
run: |
|
|
62
|
+
cd /tmp/djcrud-test/testproject
|
|
63
|
+
cat > testproject/urls.py << 'EOF'
|
|
64
|
+
from django.contrib import admin
|
|
65
|
+
from django.urls import path
|
|
66
|
+
import djcrud
|
|
67
|
+
|
|
68
|
+
urlpatterns = djcrud.site.build().urlpatterns + [
|
|
69
|
+
path("admin/", admin.site.urls),
|
|
70
|
+
]
|
|
71
|
+
EOF
|
|
72
|
+
|
|
73
|
+
- name: Run migrations
|
|
74
|
+
run: |
|
|
75
|
+
cd /tmp/djcrud-test/testproject
|
|
76
|
+
python manage.py migrate --no-input
|
|
77
|
+
|
|
78
|
+
- name: Verify installation
|
|
79
|
+
run: |
|
|
80
|
+
cd /tmp/djcrud-test/testproject
|
|
81
|
+
python manage.py check
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test-python:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.x"
|
|
21
|
+
|
|
22
|
+
- uses: browser-actions/setup-firefox@latest
|
|
23
|
+
- uses: browser-actions/setup-geckodriver@latest
|
|
24
|
+
with:
|
|
25
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
|
|
27
|
+
- name: Install package and test dependencies
|
|
28
|
+
run: |
|
|
29
|
+
pip install -U pip
|
|
30
|
+
pip install -U django
|
|
31
|
+
pip install --pre -e ".[dev]"
|
|
32
|
+
|
|
33
|
+
- name: Run unit and integration tests
|
|
34
|
+
run: pytest -m "not splinter" -n auto
|
|
35
|
+
|
|
36
|
+
- name: Run browser tests
|
|
37
|
+
run: pytest -m splinter -n 0 --splinter-headless
|
|
38
|
+
|
|
39
|
+
test-js:
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
|
|
44
|
+
- uses: actions/setup-node@v4
|
|
45
|
+
with:
|
|
46
|
+
node-version: "20"
|
|
47
|
+
cache: npm
|
|
48
|
+
|
|
49
|
+
- run: npm ci
|
|
50
|
+
- run: npm test
|
|
51
|
+
|
|
52
|
+
publish:
|
|
53
|
+
needs: [test-python, test-js]
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
with:
|
|
58
|
+
fetch-depth: 0
|
|
59
|
+
|
|
60
|
+
- uses: actions/setup-python@v5
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.x"
|
|
63
|
+
|
|
64
|
+
- name: Build package
|
|
65
|
+
run: |
|
|
66
|
+
pip install build
|
|
67
|
+
python -m build
|
|
68
|
+
|
|
69
|
+
- name: Publish to PyPI
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
djcrud-0.2.0/.gitignore
ADDED
djcrud-0.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**djcrud** is a Python/Django MVC framework that provides a thin abstraction layer over Django, enabling faster development through convention over configuration. It removes repetitive wiring while keeping Django's models, permissions, and generic views intact.
|
|
8
|
+
|
|
9
|
+
- **Language:** Python 3.8+
|
|
10
|
+
- **Framework:** Django 5.1+
|
|
11
|
+
- **Philosophy:** Structure is code, not configuration; sane defaults with surgical overrides
|
|
12
|
+
|
|
13
|
+
## Common Development Commands
|
|
14
|
+
|
|
15
|
+
### Running Tests
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Fast Python tests (parallel)
|
|
19
|
+
pytest -m "not splinter" -n auto
|
|
20
|
+
|
|
21
|
+
# Browser tests (serial, requires Firefox + geckodriver)
|
|
22
|
+
pytest -m splinter -n 0 --splinter-headless
|
|
23
|
+
|
|
24
|
+
# Single test file
|
|
25
|
+
pytest tests/test_stage0.py -v
|
|
26
|
+
|
|
27
|
+
# JavaScript tests (Vitest with happy-dom)
|
|
28
|
+
npm test
|
|
29
|
+
|
|
30
|
+
# Tutorial validation
|
|
31
|
+
pytest -m tutorial -n 0
|
|
32
|
+
|
|
33
|
+
# Full test suite
|
|
34
|
+
tox
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Important Test Markers:**
|
|
38
|
+
- `splinter` - Browser tests; must use `-n 0` (serial execution)
|
|
39
|
+
- `docs_screenshot` - Generates PNG screenshots for documentation
|
|
40
|
+
- `tutorial` - Validates literalinclude paths in docs
|
|
41
|
+
- `django_db` - Tests requiring database access
|
|
42
|
+
|
|
43
|
+
### Development Setup
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Development install with all extras
|
|
47
|
+
pip install --pre -e ".[dev,docs]"
|
|
48
|
+
|
|
49
|
+
# JavaScript tools (optional, for JS unit tests)
|
|
50
|
+
npm ci
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Note: The `--pre` flag is required for pre-release dependency versions (django-autocomplete-light>=5.1).
|
|
54
|
+
|
|
55
|
+
### Running the Example Project
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# From repository root
|
|
59
|
+
python manage.py migrate
|
|
60
|
+
python manage.py runserver
|
|
61
|
+
|
|
62
|
+
# Login at http://localhost:8000/auth/login/
|
|
63
|
+
# Username: su
|
|
64
|
+
# Password: su
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The example project in `src/djcrud_example/` includes all djcrud apps and tutorial stages (stage0-4).
|
|
68
|
+
|
|
69
|
+
### Documentation
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Build Sphinx documentation
|
|
73
|
+
make -C docs html
|
|
74
|
+
|
|
75
|
+
# Regenerate screenshots for documentation
|
|
76
|
+
pytest tests/test_docs_screenshots.py -n0 --splinter-headless
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Code Quality
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Format code (line length: 88)
|
|
83
|
+
black .
|
|
84
|
+
|
|
85
|
+
# Lint code
|
|
86
|
+
ruff check .
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Core Architecture
|
|
90
|
+
|
|
91
|
+
### Route Hierarchy Pattern
|
|
92
|
+
|
|
93
|
+
Routers nest views in code rather than urls.py configuration. Structure: **Site → Routers → Views**
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
# Example: ItemRouter contains ListView, DetailView, CreateView, etc.
|
|
97
|
+
class ItemRouter(djcrud.ModelRouter):
|
|
98
|
+
model = Item
|
|
99
|
+
|
|
100
|
+
djcrud.site.routes.append(ItemRouter)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Key files:** `src/djcrud/route.py`, `src/djcrud/router.py`
|
|
104
|
+
|
|
105
|
+
### Registry Pattern
|
|
106
|
+
|
|
107
|
+
Routes are managed by an ordered registry allowing surgical overrides by codename:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
class ItemRouter(djcrud.ModelRouter):
|
|
111
|
+
model = Item
|
|
112
|
+
routes = djcrud.ModelRouter.routes + [
|
|
113
|
+
djcrud.generic.ListView.clone(site_search=True), # Override default ListView
|
|
114
|
+
]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Key file:** `src/djcrud/registry.py`
|
|
118
|
+
|
|
119
|
+
### Clonable Pattern
|
|
120
|
+
|
|
121
|
+
Views and controllers use `.clone()` for runtime specialization without defining new module-level classes:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
MyView.clone(
|
|
125
|
+
permission_shortcode='custom',
|
|
126
|
+
site_search=True,
|
|
127
|
+
)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Key file:** `src/djcrud/clonable.py`
|
|
131
|
+
|
|
132
|
+
### Mixin Composition
|
|
133
|
+
|
|
134
|
+
Views are built from composable mixins providing focused features:
|
|
135
|
+
|
|
136
|
+
- **JsonMixin** - JSON serialization via model router
|
|
137
|
+
- **FilterMixin** - QuerySet filtering with django-filter
|
|
138
|
+
- **SearchMixin** - Full-text search
|
|
139
|
+
- **PaginationMixin** - Pagination with django-tables2
|
|
140
|
+
- **ObjectMixin** - Single object views (Detail, Update, Delete)
|
|
141
|
+
- **FormMixin** - Form handling with crispy-forms
|
|
142
|
+
- **ListActionMixin** - Bulk actions on list views
|
|
143
|
+
|
|
144
|
+
**Key directory:** `src/djcrud/views/`
|
|
145
|
+
|
|
146
|
+
### Permission Model
|
|
147
|
+
|
|
148
|
+
Three-tier permission checking: **View → Router → Django backend**
|
|
149
|
+
|
|
150
|
+
CRUD operations map to Django permissions:
|
|
151
|
+
- `add_<model>` - Create permission
|
|
152
|
+
- `change_<model>` - Update permission
|
|
153
|
+
- `delete_<model>` - Delete permission
|
|
154
|
+
- `view_<model>` - Read permission
|
|
155
|
+
|
|
156
|
+
Permissions are checked before dispatch.
|
|
157
|
+
|
|
158
|
+
**Key file:** `src/djcrud/view.py`
|
|
159
|
+
|
|
160
|
+
### ModelRouter Pattern
|
|
161
|
+
|
|
162
|
+
A **ModelRouter** automatically generates CRUD routes for a Django model:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
class ItemRouter(djcrud.ModelRouter):
|
|
166
|
+
model = Item
|
|
167
|
+
icon = 'inbox' # Bootstrap Icons name
|
|
168
|
+
color = 'primary' # Bulma color
|
|
169
|
+
|
|
170
|
+
def get_queryset(self, view):
|
|
171
|
+
"""Override to scope data per user"""
|
|
172
|
+
return self.model.objects.filter(owner=view.request.user)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Routes generated: ListView, DetailView, CreateView, UpdateView, DeleteView, DeleteObjectsView (bulk delete)
|
|
176
|
+
|
|
177
|
+
**Key files:** `src/djcrud/__init__.py`, `src/djcrud/model.py`
|
|
178
|
+
|
|
179
|
+
### Template API Pattern
|
|
180
|
+
|
|
181
|
+
Views are exposed directly to templates - no custom `get_context_data()` needed:
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
{{ view.title }}
|
|
185
|
+
{{ view.breadcrumbs }}
|
|
186
|
+
{{ view.model_meta.verbose_name_plural }}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Key file:** `src/djcrud/views/template.py`
|
|
190
|
+
|
|
191
|
+
### Autodiscovery Pattern
|
|
192
|
+
|
|
193
|
+
Like Django admin, djcrud uses autodiscovery:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# In urls.py
|
|
197
|
+
urlpatterns = djcrud.site.build().urlpatterns
|
|
198
|
+
|
|
199
|
+
# In each app's djcrud.py
|
|
200
|
+
class MyRouter(djcrud.ModelRouter):
|
|
201
|
+
model = MyModel
|
|
202
|
+
|
|
203
|
+
djcrud.site.routes.append(MyRouter)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The `site.build()` call imports all `djcrud.py` modules from installed apps.
|
|
207
|
+
|
|
208
|
+
**Key file:** `src/djcrud/__init__.py` - Site class with `autodiscover()` and `build()`
|
|
209
|
+
|
|
210
|
+
### JSON REST API
|
|
211
|
+
|
|
212
|
+
Views support dual HTML/JSON responses:
|
|
213
|
+
- Detects JSON requests via Content-Type or Accept headers
|
|
214
|
+
- REST methods: GET, POST, PUT, PATCH, DELETE
|
|
215
|
+
- JSON serialization via `ModelRouter.serialize()`
|
|
216
|
+
- Swagger/OpenAPI schema generation available
|
|
217
|
+
|
|
218
|
+
**Key file:** `src/djcrud/views/json.py`
|
|
219
|
+
|
|
220
|
+
## Project Structure
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
src/djcrud/ Core framework
|
|
224
|
+
src/djcrud_bulma/ Bulma CSS template pack with static assets
|
|
225
|
+
src/djcrud_auth/ Authentication router (login, logout, password)
|
|
226
|
+
src/djcrud_api/ JSON REST API with Swagger UI and token auth
|
|
227
|
+
src/djcrud_dal/ Django-autocomplete-light integration
|
|
228
|
+
src/djcrud_dal_topbar/ Site search in navbar
|
|
229
|
+
src/djcrud_history/ Audit logging with LogEntry models
|
|
230
|
+
src/djcrud_debug/ Route introspection (debug only, superuser)
|
|
231
|
+
src/djcrud_example/ Example Django project with tutorial apps (stage0-4)
|
|
232
|
+
tests/ Test suite with conftest.py fixtures
|
|
233
|
+
docs/ Sphinx documentation
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Philosophy
|
|
237
|
+
|
|
238
|
+
These principles guide djcrud's design (from `docs/philosophy.rst`):
|
|
239
|
+
|
|
240
|
+
- **Structure is code, not configuration** - Routers and views nested in Python, not urls.py
|
|
241
|
+
- **Sane defaults, surgical overrides** - Works out of the box; customize via `clone()` and registry
|
|
242
|
+
- **View is the template API** - View object exposed to templates directly
|
|
243
|
+
- **Security and data scope in one place** - Permissions and queryset filtering in router
|
|
244
|
+
- **Menus introspected, not hardcoded** - Views carry tags; navigation built from `get_tagged_views()`
|
|
245
|
+
- **Composition over monoliths** - Generic views are stacks of small mixins
|
|
246
|
+
- **Django all the way down** - Uses Django's `user.has_perm()`, generic views, standard urlpatterns
|
|
247
|
+
|
|
248
|
+
## JavaScript Architecture
|
|
249
|
+
|
|
250
|
+
- **Custom elements** with light DOM (no Shadow DOM)
|
|
251
|
+
- **ES modules**, no bundler
|
|
252
|
+
- **Unpoly compilers** for progressive enhancement
|
|
253
|
+
- Listen for `up:fragment:inserted` for Unpoly compatibility
|
|
254
|
+
- Config via HTML attributes and `data-*` hooks
|
|
255
|
+
|
|
256
|
+
**JavaScript files:** `src/djcrud_bulma/static/djcrud_bulma/js/`
|
|
257
|
+
|
|
258
|
+
## Important Dependencies
|
|
259
|
+
|
|
260
|
+
**Core:**
|
|
261
|
+
- django-tables2 (table rendering)
|
|
262
|
+
- django-crispy-forms (form layout)
|
|
263
|
+
- django-filter (QuerySet filtering)
|
|
264
|
+
- django-autocomplete-light (autocomplete widgets)
|
|
265
|
+
- djhacker (model patching)
|
|
266
|
+
|
|
267
|
+
**Install order matters:** `dal` and `dal_select2` must come **before** `django.contrib.admin` in INSTALLED_APPS
|
|
268
|
+
|
|
269
|
+
**Frontend:**
|
|
270
|
+
- Unpoly.js (AJAX navigation)
|
|
271
|
+
- Bootstrap Icons
|
|
272
|
+
- Bulma CSS (with djcrud_bulma template pack)
|
|
273
|
+
|
|
274
|
+
## Extension Packages
|
|
275
|
+
|
|
276
|
+
- **djcrud_bulma** - Bulma CSS template pack with HTML templates and static assets
|
|
277
|
+
- **djcrud_auth** - Authentication views (login, logout, password change)
|
|
278
|
+
- **djcrud_api** - JSON REST API with schema, Swagger UI, Bearer token auth
|
|
279
|
+
- **djcrud_dal** - Zero-config autocomplete for relation fields
|
|
280
|
+
- **djcrud_dal_topbar** - Site search widget in navbar
|
|
281
|
+
- **djcrud_debug** - Debug routing introspection (superuser only)
|
|
282
|
+
- **djcrud_history** - Audit logging and global log-entry browser
|
djcrud-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: djcrud
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Django CRUD utilities
|
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: django>=5.1
|
|
20
|
+
Requires-Dist: django-tables2>=2.7
|
|
21
|
+
Requires-Dist: django-crispy-forms>=2.0
|
|
22
|
+
Requires-Dist: django-filter
|
|
23
|
+
Requires-Dist: django-autocomplete-light>=5.1rc1
|
|
24
|
+
Requires-Dist: django-querysetsequence>=0.11
|
|
25
|
+
Requires-Dist: djhacker
|
|
26
|
+
Requires-Dist: crispy-bulma>=0.1
|
|
27
|
+
Provides-Extra: api
|
|
28
|
+
Provides-Extra: swagger
|
|
29
|
+
Provides-Extra: bulma
|
|
30
|
+
Requires-Dist: django-crispy-forms>=2.0; extra == "bulma"
|
|
31
|
+
Requires-Dist: crispy-bulma>=0.1; extra == "bulma"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-django>=4.5; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-splinter>=3.3; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
38
|
+
Requires-Dist: tox>=4; extra == "dev"
|
|
39
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
41
|
+
Provides-Extra: docs
|
|
42
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
43
|
+
Requires-Dist: furo; extra == "docs"
|
|
44
|
+
|
|
45
|
+
# djcrud
|
|
46
|
+
|
|
47
|
+
**Faster Django development by getting more out of less.**
|
|
48
|
+
|
|
49
|
+
djcrud is a thin MVC layer on top of Django. Declare controllers and views in
|
|
50
|
+
code, get secure CRUD and routing by default, and expose the view object
|
|
51
|
+
directly to templates.
|
|
52
|
+
|
|
53
|
+
Read the [philosophy](https://jpic.github.io/djcrud/philosophy.html) for the
|
|
54
|
+
full rationale.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install --pre djcrud
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Note: The `--pre` flag is required for pre-release dependency versions.
|
|
63
|
+
|
|
64
|
+
See [installation](https://jpic.github.io/djcrud/install.html) for setup, or
|
|
65
|
+
try the [demo](https://jpic.github.io/djcrud/demo.html) to explore the example
|
|
66
|
+
project.
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# myapp/djcrud.py
|
|
72
|
+
import djcrud
|
|
73
|
+
|
|
74
|
+
from .models import YourModel
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class YourModelRouter(djcrud.ModelRouter):
|
|
78
|
+
model = YourModel
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
djcrud.site.routes.append(YourModelRouter)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
# urls.py
|
|
86
|
+
import djcrud
|
|
87
|
+
|
|
88
|
+
urlpatterns = djcrud.site.build().urlpatterns
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Add `myapp` to `INSTALLED_APPS`. `build()` autodiscovers each app's `djcrud.py`
|
|
92
|
+
(like Django admin) — the import runs `routes.append()` before the route
|
|
93
|
+
registry is built.
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
- [Philosophy](https://jpic.github.io/djcrud/philosophy.html)
|
|
98
|
+
- [Install](https://jpic.github.io/djcrud/install.html)
|
|
99
|
+
- [Demo](https://jpic.github.io/djcrud/demo.html) — Try the example project
|
|
100
|
+
- [Tutorial](https://jpic.github.io/djcrud/tutorial/)
|
|
101
|
+
- [Reference](https://jpic.github.io/djcrud/reference/)
|
|
102
|
+
|
|
103
|
+
## Contributing
|
|
104
|
+
|
|
105
|
+
See the [contributing guide](https://jpic.github.io/djcrud/contributing.html)
|
|
106
|
+
for development setup, running tests, updating documentation screenshots, and
|
|
107
|
+
JavaScript conventions. Source: [`docs/contributing.rst`](docs/contributing.rst).
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|