accrete 0.0.112__tar.gz → 0.0.113__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.
- {accrete-0.0.112 → accrete-0.0.113}/PKG-INFO +1 -1
- accrete-0.0.113/accrete/contrib/log/admin.py +43 -0
- accrete-0.0.113/accrete/contrib/log/apps.py +13 -0
- accrete-0.0.113/accrete/contrib/log/helper.py +79 -0
- accrete-0.0.113/accrete/contrib/log/migrations/0001_initial.py +38 -0
- accrete-0.0.113/accrete/contrib/log/migrations/0002_log_user_alter_log_new_value_type_and_more.py +31 -0
- accrete-0.0.113/accrete/contrib/log/migrations/0003_alter_log_tenant.py +20 -0
- accrete-0.0.113/accrete/contrib/log/migrations/0004_logconfig_logconfigfield.py +47 -0
- accrete-0.0.113/accrete/contrib/log/migrations/0005_logconfig_exclude_fields_and_more.py +29 -0
- accrete-0.0.113/accrete/contrib/log/models.py +229 -0
- accrete-0.0.113/accrete/contrib/log/queries.py +34 -0
- accrete-0.0.113/accrete/contrib/log/signals.py +62 -0
- accrete-0.0.113/accrete/contrib/system_mail/views.py +3 -0
- accrete-0.0.113/accrete/contrib/ui/templates/ui/form_error.html +11 -0
- accrete-0.0.113/accrete/contrib/user_registration/migrations/__init__.py +0 -0
- accrete-0.0.113/accrete/contrib/user_registration/tests.py +3 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/managers.py +7 -0
- accrete-0.0.113/accrete/migrations/0003_remove_member_name.py +17 -0
- accrete-0.0.113/accrete/migrations/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/models.py +3 -17
- {accrete-0.0.112 → accrete-0.0.113}/pyproject.toml +1 -1
- {accrete-0.0.112 → accrete-0.0.113}/.gitignore +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/LICENSE +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/README.md +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/config.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/__init__.py +0 -0
- {accrete-0.0.112/accrete/contrib/sequence → accrete-0.0.113/accrete/contrib/log}/__init__.py +0 -0
- {accrete-0.0.112/accrete/contrib/sequence → accrete-0.0.113/accrete/contrib/log}/migrations/__init__.py +0 -0
- {accrete-0.0.112/accrete/contrib/sequence → accrete-0.0.113/accrete/contrib/log}/tests.py +0 -0
- {accrete-0.0.112/accrete/contrib/sequence → accrete-0.0.113/accrete/contrib/log}/views.py +0 -0
- {accrete-0.0.112/accrete/contrib/system_mail → accrete-0.0.113/accrete/contrib/sequence}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/migrations/0001_initial.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/migrations/0002_alter_sequence_name.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/migrations/0003_alter_sequence_tenant.py +0 -0
- {accrete-0.0.112/accrete/contrib/system_mail → accrete-0.0.113/accrete/contrib/sequence}/migrations/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/sequence/queries.py +0 -0
- {accrete-0.0.112/accrete/contrib/system_mail → accrete-0.0.113/accrete/contrib/sequence}/tests.py +0 -0
- {accrete-0.0.112/accrete/contrib/system_mail → accrete-0.0.113/accrete/contrib/sequence}/views.py +0 -0
- {accrete-0.0.112/accrete/contrib/ui/migrations → accrete-0.0.113/accrete/contrib/system_mail}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/migrations/0001_initial.py +0 -0
- {accrete-0.0.112/accrete/contrib/ui/templatetags → accrete-0.0.113/accrete/contrib/system_mail/migrations}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/system_mail/tasks.py +0 -0
- {accrete-0.0.112/accrete/contrib/ui → accrete-0.0.113/accrete/contrib/system_mail}/tests.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/context.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/filter.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/middleware.py +0 -0
- {accrete-0.0.112/accrete/contrib/user → accrete-0.0.113/accrete/contrib/ui/migrations}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/LICENSE +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/README.md +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/bulma.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/bulma.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/bulma.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/bulma.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/bulma.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/bulma.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.min.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/package.json +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/animations.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/animations.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/animations.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/generic.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/generic.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/generic.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/minireset.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/minireset.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/minireset.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/skeleton.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/skeleton.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/base/skeleton.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/card.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/card.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/card.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/dropdown.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/dropdown.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/dropdown.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/menu.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/menu.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/menu.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/message.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/message.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/message.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/modal.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/modal.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/modal.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/navbar.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/navbar.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/navbar.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/pagination.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/pagination.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/pagination.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/panel.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/panel.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/panel.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/tabs.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/tabs.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/components/tabs.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/block.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/block.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/block.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/box.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/box.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/box.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/button.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/button.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/button.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/content.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/content.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/content.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/delete.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/delete.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/delete.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/icon.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/icon.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/icon.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/image.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/image.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/image.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/loader.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/loader.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/loader.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/notification.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/notification.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/notification.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/progress.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/progress.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/progress.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/table.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/table.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/table.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/tag.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/tag.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/tag.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/title.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/title.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/elements/title.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/file.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/file.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/file.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/input-textarea.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/input-textarea.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/input-textarea.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/select.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/select.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/select.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/shared.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/shared.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/shared.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/tools.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/tools.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/form/tools.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/columns.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/columns.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/columns.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/grid.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/grid.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/grid/grid.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/border.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/border.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/border.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/color.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/color.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/color.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/float.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/float.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/float.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/gap.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/gap.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/gap.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/other.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/other.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/other.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/overflow.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/overflow.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/overflow.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/position.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/position.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/position.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/spacing.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/spacing.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/spacing.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/typography.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/typography.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/typography.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/visibility.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/visibility.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/helpers/visibility.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/container.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/footer.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/footer.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/footer.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/hero.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/hero.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/hero.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/level.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/level.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/level.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/media.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/media.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/media.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/section.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/section.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/layout/section.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/dark.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/dark.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/dark.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/light.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/light.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/light.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/setup.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/setup.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/themes/setup.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/_index.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/controls.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/controls.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/controls.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/extends.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/extends.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/extends.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/functions.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/mixins.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/mixins.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/sass/utilities/mixins.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/css/accrete.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/css/accrete.css.map +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/css/accrete.scss +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/css/fa.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/css/icons.css +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/icons/Logo.svg +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/icons/accrete.svg +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/js/alpine-sort3.14.1.js +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/js/alpine3.14.1.js +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/js/filter.js +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/js/htmx.min.js +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-brands-400.ttf +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-brands-400.woff2 +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-regular-400.ttf +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-regular-400.woff2 +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-solid-900.ttf +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-solid-900.woff2 +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-v4compatibility.ttf +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/static/webfonts/fa-v4compatibility.woff2 +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/attrs.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/date.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/email.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/file.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/input.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/select.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/text.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/django/forms/widgets/textarea.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/content_right.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/filter/filter.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/filter/query_input.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/filter/query_operator.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/filter/query_params.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/filter/query_tags.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/layout.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/list.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/list_update.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/message.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/modal.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/oob.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/table.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/table_row_update.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/widgets/model_search_select.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html +0 -0
- {accrete-0.0.112/accrete/contrib/user/migrations → accrete-0.0.113/accrete/contrib/ui/templatetags}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/templatetags/ui.py +0 -0
- {accrete-0.0.112/accrete/contrib/user → accrete-0.0.113/accrete/contrib/ui}/tests.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/urls.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/views.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/widgets/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/ui/widgets/search_select.py +0 -0
- {accrete-0.0.112/accrete/contrib/user_registration → accrete-0.0.113/accrete/contrib/user}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/locale/de/LC_MESSAGES/django.mo +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/locale/de/LC_MESSAGES/django.po +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/middleware.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/migrations/0001_initial.py +0 -0
- {accrete-0.0.112/accrete/contrib/user_registration → accrete-0.0.113/accrete/contrib/user}/migrations/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/templates/user/change_email.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/templates/user/change_password.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/templates/user/login.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/templates/user/user_form.html +0 -0
- {accrete-0.0.112/accrete/contrib/user_registration → accrete-0.0.113/accrete/contrib/user}/tests.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/urls.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user/views.py +0 -0
- {accrete-0.0.112/accrete/migrations → accrete-0.0.113/accrete/contrib/user_registration}/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/admin.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/apps.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/config.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/migrations/0001_initial.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/templates/user_registration/mail_templates/confirmation_mail.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/templates/user_registration/registration.html +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/urls.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/contrib/user_registration/views.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/middleware.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/migrations/0001_initial.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/migrations/0002_initial.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/storage.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/tenant.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/tests.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/urls.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/__init__.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/dates.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/forms.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/log.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/models.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/utils/views.py +0 -0
- {accrete-0.0.112 → accrete-0.0.113}/accrete/views.py +0 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
import django.apps
|
2
|
+
from django.contrib import admin
|
3
|
+
from django import forms
|
4
|
+
from . import models
|
5
|
+
|
6
|
+
installed_models = django.apps.apps.get_models(
|
7
|
+
include_auto_created=True, include_swapped=True
|
8
|
+
)
|
9
|
+
model_choices = [(
|
10
|
+
f'{m._meta.app_label}.{m._meta.model_name}',
|
11
|
+
f'{m._meta.app_label}.{m._meta.verbose_name}'
|
12
|
+
) for m in installed_models]
|
13
|
+
|
14
|
+
|
15
|
+
class LogConfigForm(forms.ModelForm):
|
16
|
+
|
17
|
+
model = forms.ChoiceField(choices=model_choices)
|
18
|
+
|
19
|
+
|
20
|
+
class LogConfigFieldInLine(admin.TabularInline):
|
21
|
+
|
22
|
+
model = models.LogConfigField
|
23
|
+
|
24
|
+
|
25
|
+
class LogConfigAdmin(admin.ModelAdmin):
|
26
|
+
|
27
|
+
model = models.LogConfig
|
28
|
+
list_display = ('model', 'ignore_errors')
|
29
|
+
search_fields = ('pk', 'model')
|
30
|
+
list_filter = ['ignore_errors']
|
31
|
+
form = LogConfigForm
|
32
|
+
inlines = [LogConfigFieldInLine]
|
33
|
+
|
34
|
+
def formfield_for_choice_field(self, db_field, request, **kwargs):
|
35
|
+
if db_field.name == "model":
|
36
|
+
kwargs["choices"] = [
|
37
|
+
("accepted", "Accepted"),
|
38
|
+
("denied", "Denied"),
|
39
|
+
]
|
40
|
+
return super().formfield_for_choice_field(db_field, request, **kwargs)
|
41
|
+
|
42
|
+
|
43
|
+
admin.site.register(models.LogConfig, LogConfigAdmin)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from django.apps import AppConfig
|
2
|
+
from django.db.models.signals import post_save
|
3
|
+
|
4
|
+
|
5
|
+
class LogConfig(AppConfig):
|
6
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
7
|
+
name = 'accrete.contrib.log'
|
8
|
+
|
9
|
+
def ready(self):
|
10
|
+
from . import signals
|
11
|
+
post_save.connect(
|
12
|
+
signals.create_log, weak=False, dispatch_uid="accrete.contrib.log"
|
13
|
+
)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
from django.db import models
|
2
|
+
from django.db.models.query import RawQuerySet
|
3
|
+
from django.forms import model_to_dict
|
4
|
+
|
5
|
+
from .models import Log, LogConfig
|
6
|
+
|
7
|
+
TYPES_FK = ['AutoField', 'BigAutoField', 'ForeignKey']
|
8
|
+
TYPES_INT = ['IntegerField', 'PositiveSmallIntegerField']
|
9
|
+
TYPES_DECIMAL = ['DecimalField']
|
10
|
+
TYPES_FLOAT = ['FloatField']
|
11
|
+
TYPES_STR = ['CharField', 'TextField']
|
12
|
+
TYPES_BOOL = ['BooleanField']
|
13
|
+
TYPES_DATETIME = ['DateTimeField']
|
14
|
+
TYPES_DATE = ['DateField']
|
15
|
+
TYPES_TIME = ['TimeField']
|
16
|
+
|
17
|
+
|
18
|
+
def internal_type_to_log_type(field: models.Field):
|
19
|
+
internal_type = field.get_internal_type()
|
20
|
+
if internal_type in TYPES_FK:
|
21
|
+
return 'fk'
|
22
|
+
if internal_type in TYPES_INT:
|
23
|
+
return 'int'
|
24
|
+
if internal_type in TYPES_FLOAT:
|
25
|
+
return 'float'
|
26
|
+
if internal_type in TYPES_DECIMAL:
|
27
|
+
return 'decimal'
|
28
|
+
if internal_type in TYPES_BOOL:
|
29
|
+
return 'bool'
|
30
|
+
if internal_type in TYPES_STR:
|
31
|
+
return 'str'
|
32
|
+
if internal_type in TYPES_DATE:
|
33
|
+
return 'date'
|
34
|
+
if internal_type in TYPES_DATETIME:
|
35
|
+
return 'datetime'
|
36
|
+
|
37
|
+
|
38
|
+
def log_state_to_dict(logs: RawQuerySet) -> tuple[dict, dict]:
|
39
|
+
state = dict()
|
40
|
+
info = dict()
|
41
|
+
if not logs:
|
42
|
+
return state, info
|
43
|
+
for log in logs:
|
44
|
+
state.update({log.field: log.cast_value()})
|
45
|
+
info.update({log.field: {'new_value_type': log.new_value_type}})
|
46
|
+
return state, info
|
47
|
+
|
48
|
+
|
49
|
+
def log_value_to_instance_value(log: Log):
|
50
|
+
if log.new_value_type == 'bool':
|
51
|
+
return bool(log.new_value == 'True')
|
52
|
+
|
53
|
+
if log.new_value == '':
|
54
|
+
return None
|
55
|
+
if log.new_value_type in ['fk', 'int']:
|
56
|
+
return int(log.new_value)
|
57
|
+
|
58
|
+
|
59
|
+
def get_instance_state(instance: models.Model):
|
60
|
+
state = model_to_dict(instance)
|
61
|
+
cleaned_state = dict()
|
62
|
+
log_config = LogConfig.objects.filter(
|
63
|
+
model=f'{instance._meta.app_label}.{instance._meta.model_name}'
|
64
|
+
).prefetch_related('fields').first()
|
65
|
+
if not log_config:
|
66
|
+
return cleaned_state
|
67
|
+
all_fields = list(map(lambda x: x.name, instance._meta.get_fields()))
|
68
|
+
if log_config.exclude_fields:
|
69
|
+
fields_to_log = list(f for f in all_fields if f not in log_config.fields.all().values_list('field_name', flat=True))
|
70
|
+
else:
|
71
|
+
fields_to_log = log_config.fields.all().values_list('field_name', flat=True)
|
72
|
+
|
73
|
+
for f, v in state.items():
|
74
|
+
if isinstance(v, (list, tuple, dict)):
|
75
|
+
continue
|
76
|
+
if f not in fields_to_log:
|
77
|
+
continue
|
78
|
+
cleaned_state.update({f: v})
|
79
|
+
return cleaned_state
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Generated by Django 5.1.1 on 2025-01-08 20:04
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
initial = True
|
10
|
+
|
11
|
+
dependencies = [
|
12
|
+
('accrete', '0002_initial'),
|
13
|
+
]
|
14
|
+
|
15
|
+
operations = [
|
16
|
+
migrations.CreateModel(
|
17
|
+
name='Log',
|
18
|
+
fields=[
|
19
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
20
|
+
('model', models.CharField(help_text='Combination of app label and model name seperated by a dot', max_length=255, verbose_name='Model')),
|
21
|
+
('field', models.CharField(max_length=255, verbose_name='Field')),
|
22
|
+
('object_id', models.BigIntegerField(verbose_name='Object ID')),
|
23
|
+
('log_date', models.DateTimeField(auto_now_add=True, verbose_name='Date')),
|
24
|
+
('old_value_type', models.CharField(choices=[('fk', 'Foreign Key'), ('int', 'Integer'), ('float', 'Float'), ('decimal', 'Decimal'), ('bool', 'Boolean'), ('str', 'String')], max_length=100, verbose_name='Old Value Type')),
|
25
|
+
('new_value_type', models.CharField(choices=[('fk', 'Foreign Key'), ('int', 'Integer'), ('float', 'Float'), ('decimal', 'Decimal'), ('bool', 'Boolean'), ('str', 'String')], max_length=100, verbose_name='New Value Type')),
|
26
|
+
('old_value', models.TextField(blank=True, null=True, verbose_name='Old Value')),
|
27
|
+
('new_value', models.TextField(blank=True, null=True, verbose_name='New Value')),
|
28
|
+
('tenant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accrete.tenant', verbose_name='Tenant')),
|
29
|
+
],
|
30
|
+
options={
|
31
|
+
'verbose_name': 'Log',
|
32
|
+
'verbose_name_plural': 'Logs',
|
33
|
+
'db_table': 'accrete_log',
|
34
|
+
'indexes': [models.Index(fields=['model', 'object_id'], name='accrete_log_model_cf888c_idx')],
|
35
|
+
'constraints': [models.UniqueConstraint(fields=('model', 'field', 'object_id', 'log_date'), name='unique_group_fields')],
|
36
|
+
},
|
37
|
+
),
|
38
|
+
]
|
accrete-0.0.113/accrete/contrib/log/migrations/0002_log_user_alter_log_new_value_type_and_more.py
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Generated by Django 5.1.1 on 2025-01-10 07:56
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.conf import settings
|
5
|
+
from django.db import migrations, models
|
6
|
+
|
7
|
+
|
8
|
+
class Migration(migrations.Migration):
|
9
|
+
|
10
|
+
dependencies = [
|
11
|
+
('log', '0001_initial'),
|
12
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
13
|
+
]
|
14
|
+
|
15
|
+
operations = [
|
16
|
+
migrations.AddField(
|
17
|
+
model_name='log',
|
18
|
+
name='user',
|
19
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='logs', to=settings.AUTH_USER_MODEL),
|
20
|
+
),
|
21
|
+
migrations.AlterField(
|
22
|
+
model_name='log',
|
23
|
+
name='new_value_type',
|
24
|
+
field=models.CharField(choices=[('fk', 'Foreign Key'), ('int', 'Integer'), ('float', 'Float'), ('decimal', 'Decimal'), ('bool', 'Boolean'), ('str', 'String'), ('date', 'Date'), ('datetime', 'Date Time')], max_length=100, verbose_name='New Value Type'),
|
25
|
+
),
|
26
|
+
migrations.AlterField(
|
27
|
+
model_name='log',
|
28
|
+
name='old_value_type',
|
29
|
+
field=models.CharField(choices=[('fk', 'Foreign Key'), ('int', 'Integer'), ('float', 'Float'), ('decimal', 'Decimal'), ('bool', 'Boolean'), ('str', 'String'), ('date', 'Date'), ('datetime', 'Date Time')], max_length=100, verbose_name='Old Value Type'),
|
30
|
+
),
|
31
|
+
]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Generated by Django 5.1.1 on 2025-01-10 08:02
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
('accrete', '0003_remove_member_name'),
|
11
|
+
('log', '0002_log_user_alter_log_new_value_type_and_more'),
|
12
|
+
]
|
13
|
+
|
14
|
+
operations = [
|
15
|
+
migrations.AlterField(
|
16
|
+
model_name='log',
|
17
|
+
name='tenant',
|
18
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='accrete.tenant', verbose_name='Tenant'),
|
19
|
+
),
|
20
|
+
]
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Generated by Django 5.1.1 on 2025-01-10 15:20
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
import django.db.models.functions.text
|
5
|
+
from django.db import migrations, models
|
6
|
+
|
7
|
+
|
8
|
+
class Migration(migrations.Migration):
|
9
|
+
|
10
|
+
dependencies = [
|
11
|
+
('log', '0003_alter_log_tenant'),
|
12
|
+
]
|
13
|
+
|
14
|
+
operations = [
|
15
|
+
migrations.CreateModel(
|
16
|
+
name='LogConfig',
|
17
|
+
fields=[
|
18
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
19
|
+
('model', models.CharField(help_text='Combination of app label and model name seperated by a dot', max_length=255, verbose_name='Model')),
|
20
|
+
('ignore_errors', models.BooleanField(default=False, help_text='IF true, exceptions during log creation will be ignored', verbose_name='Ignore Errors')),
|
21
|
+
],
|
22
|
+
options={
|
23
|
+
'verbose_name': 'Log Configuration',
|
24
|
+
'verbose_name_plural': 'Log Configs',
|
25
|
+
'db_table': 'accrete_log_config',
|
26
|
+
'ordering': [django.db.models.functions.text.Lower('model')],
|
27
|
+
'indexes': [models.Index(fields=['model'], name='accrete_log_model_a89071_idx')],
|
28
|
+
'constraints': [models.UniqueConstraint(fields=('model',), name='unique_model')],
|
29
|
+
},
|
30
|
+
),
|
31
|
+
migrations.CreateModel(
|
32
|
+
name='LogConfigField',
|
33
|
+
fields=[
|
34
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
35
|
+
('field_name', models.CharField(help_text='Name of the field to log', max_length=255, verbose_name='Field Name')),
|
36
|
+
('log_config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='log.logconfig', verbose_name='Log Configuration')),
|
37
|
+
],
|
38
|
+
options={
|
39
|
+
'verbose_name': 'Log Configuration Field',
|
40
|
+
'verbose_name_plural': 'Log Configuration Fields',
|
41
|
+
'db_table': 'accrete_log_config_field',
|
42
|
+
'ordering': [django.db.models.functions.text.Lower('field_name')],
|
43
|
+
'indexes': [models.Index(fields=['log_config'], name='accrete_log_log_con_22f45e_idx')],
|
44
|
+
'constraints': [models.UniqueConstraint(fields=('log_config', 'field_name'), name='unique_config_field_name')],
|
45
|
+
},
|
46
|
+
),
|
47
|
+
]
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Generated by Django 5.1.1 on 2025-01-12 09:24
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
('log', '0004_logconfig_logconfigfield'),
|
11
|
+
]
|
12
|
+
|
13
|
+
operations = [
|
14
|
+
migrations.AddField(
|
15
|
+
model_name='logconfig',
|
16
|
+
name='exclude_fields',
|
17
|
+
field=models.BooleanField(default=False, help_text='If set, Log Configuration Fields will be excluded from logging. Otherwise only configured fields will be logged.', verbose_name='Exclude Fields'),
|
18
|
+
),
|
19
|
+
migrations.AlterField(
|
20
|
+
model_name='logconfig',
|
21
|
+
name='ignore_errors',
|
22
|
+
field=models.BooleanField(default=False, help_text='If set, exceptions during log creation will be ignored', verbose_name='Ignore Errors'),
|
23
|
+
),
|
24
|
+
migrations.AlterField(
|
25
|
+
model_name='logconfigfield',
|
26
|
+
name='log_config',
|
27
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='log.logconfig', verbose_name='Log Configuration'),
|
28
|
+
),
|
29
|
+
]
|
@@ -0,0 +1,229 @@
|
|
1
|
+
from decimal import Decimal
|
2
|
+
from datetime import date, datetime
|
3
|
+
|
4
|
+
from django.conf import settings
|
5
|
+
from django.db.models.functions import Lower
|
6
|
+
from django.utils.translation import gettext_lazy as _
|
7
|
+
from django.db import models
|
8
|
+
|
9
|
+
|
10
|
+
class Log(models.Model):
|
11
|
+
|
12
|
+
class Meta:
|
13
|
+
verbose_name = _('Log')
|
14
|
+
verbose_name_plural = _('Logs')
|
15
|
+
db_table = 'accrete_log'
|
16
|
+
indexes = [
|
17
|
+
models.Index(fields=['model', 'object_id'])
|
18
|
+
]
|
19
|
+
constraints = [
|
20
|
+
models.UniqueConstraint(
|
21
|
+
name='unique_group_fields',
|
22
|
+
fields=('model', 'field', 'object_id', 'log_date')
|
23
|
+
)
|
24
|
+
]
|
25
|
+
|
26
|
+
tenant = models.ForeignKey(
|
27
|
+
verbose_name=_('Tenant'),
|
28
|
+
to='accrete.Tenant',
|
29
|
+
on_delete=models.CASCADE,
|
30
|
+
null=True,
|
31
|
+
blank=True
|
32
|
+
)
|
33
|
+
|
34
|
+
model = models.CharField(
|
35
|
+
verbose_name=_('Model'),
|
36
|
+
max_length=255,
|
37
|
+
help_text='Combination of app label and model name seperated by a dot'
|
38
|
+
)
|
39
|
+
|
40
|
+
field = models.CharField(
|
41
|
+
verbose_name=_('Field'),
|
42
|
+
max_length=255
|
43
|
+
)
|
44
|
+
|
45
|
+
object_id = models.BigIntegerField(
|
46
|
+
verbose_name='Object ID'
|
47
|
+
)
|
48
|
+
|
49
|
+
log_date = models.DateTimeField(
|
50
|
+
verbose_name=_('Date'),
|
51
|
+
auto_now_add=True
|
52
|
+
)
|
53
|
+
|
54
|
+
old_value_type = models.CharField(
|
55
|
+
verbose_name=_('Old Value Type'),
|
56
|
+
choices=[
|
57
|
+
('fk', 'Foreign Key'),
|
58
|
+
('int', 'Integer'),
|
59
|
+
('float', 'Float'),
|
60
|
+
('decimal', 'Decimal'),
|
61
|
+
('bool', 'Boolean'),
|
62
|
+
('str', 'String'),
|
63
|
+
('date', 'Date'),
|
64
|
+
('datetime', 'Date Time')
|
65
|
+
],
|
66
|
+
max_length=100,
|
67
|
+
)
|
68
|
+
|
69
|
+
new_value_type = models.CharField(
|
70
|
+
verbose_name=_('New Value Type'),
|
71
|
+
choices=[
|
72
|
+
('fk', 'Foreign Key'),
|
73
|
+
('int', 'Integer'),
|
74
|
+
('float', 'Float'),
|
75
|
+
('decimal', 'Decimal'),
|
76
|
+
('bool', 'Boolean'),
|
77
|
+
('str', 'String'),
|
78
|
+
('date', 'Date'),
|
79
|
+
('datetime', 'Date Time')
|
80
|
+
],
|
81
|
+
max_length=100
|
82
|
+
)
|
83
|
+
|
84
|
+
old_value = models.TextField(
|
85
|
+
verbose_name=_('Old Value'),
|
86
|
+
null=True,
|
87
|
+
blank=True
|
88
|
+
)
|
89
|
+
|
90
|
+
new_value = models.TextField(
|
91
|
+
verbose_name=_('New Value'),
|
92
|
+
null=True,
|
93
|
+
blank=True
|
94
|
+
)
|
95
|
+
|
96
|
+
user = models.ForeignKey(
|
97
|
+
to=settings.AUTH_USER_MODEL,
|
98
|
+
related_name='logs',
|
99
|
+
on_delete=models.SET_NULL,
|
100
|
+
null=True,
|
101
|
+
blank=True
|
102
|
+
)
|
103
|
+
|
104
|
+
def __str__(self):
|
105
|
+
return f'{self.model}.{self.field},{self.object_id}'
|
106
|
+
|
107
|
+
def cast_value(self):
|
108
|
+
if self.new_value is None:
|
109
|
+
return None
|
110
|
+
if self.new_value_type == 'fk':
|
111
|
+
return self.cast_fk()
|
112
|
+
if self.new_value_type == 'int':
|
113
|
+
return self.cast_int()
|
114
|
+
if self.new_value_type == 'float':
|
115
|
+
return self.cast_float()
|
116
|
+
if self.new_value_type == 'decimal':
|
117
|
+
return self.cast_decimal()
|
118
|
+
if self.new_value_type == 'bool':
|
119
|
+
return self.cast_bool()
|
120
|
+
if self.new_value_type == 'str':
|
121
|
+
return self.cast_str()
|
122
|
+
if self.new_value_type == 'date':
|
123
|
+
return self.cast_date()
|
124
|
+
if self.new_value_type == 'datetime':
|
125
|
+
return self.cast_date_time()
|
126
|
+
|
127
|
+
def cast_fk(self):
|
128
|
+
return self.cast_int()
|
129
|
+
|
130
|
+
def cast_int(self):
|
131
|
+
if self.new_value == '':
|
132
|
+
return None
|
133
|
+
return int(self.new_value)
|
134
|
+
|
135
|
+
def cast_float(self):
|
136
|
+
if self.new_value == '':
|
137
|
+
return 0.0
|
138
|
+
return float(self.new_value)
|
139
|
+
|
140
|
+
def cast_decimal(self):
|
141
|
+
if self.new_value == '':
|
142
|
+
return Decimal(0)
|
143
|
+
return Decimal(self.new_value)
|
144
|
+
|
145
|
+
def cast_bool(self):
|
146
|
+
return self.new_value == 'True'
|
147
|
+
|
148
|
+
def cast_str(self):
|
149
|
+
return self.new_value
|
150
|
+
|
151
|
+
def cast_date(self):
|
152
|
+
if self.new_value == '':
|
153
|
+
return None
|
154
|
+
return date.fromisoformat(str(self.new_value))
|
155
|
+
|
156
|
+
def cast_date_time(self):
|
157
|
+
if self.new_value == '':
|
158
|
+
return None
|
159
|
+
return datetime.fromisoformat(self.new_value)
|
160
|
+
|
161
|
+
|
162
|
+
class LogConfig(models.Model):
|
163
|
+
|
164
|
+
class Meta:
|
165
|
+
verbose_name = _('Log Configuration')
|
166
|
+
verbose_name_plural = _('Log Configs')
|
167
|
+
db_table = 'accrete_log_config'
|
168
|
+
ordering = [Lower('model')]
|
169
|
+
indexes = [
|
170
|
+
models.Index(fields=['model'])
|
171
|
+
]
|
172
|
+
constraints = [
|
173
|
+
models.UniqueConstraint(
|
174
|
+
name='unique_model',
|
175
|
+
fields=('model',)
|
176
|
+
)
|
177
|
+
]
|
178
|
+
|
179
|
+
model = models.CharField(
|
180
|
+
verbose_name=_('Model'),
|
181
|
+
max_length=255,
|
182
|
+
help_text=_('Combination of app label and model name seperated by a dot')
|
183
|
+
)
|
184
|
+
|
185
|
+
ignore_errors = models.BooleanField(
|
186
|
+
verbose_name=_('Ignore Errors'),
|
187
|
+
default=False,
|
188
|
+
help_text=_('If set, exceptions during log creation will be ignored')
|
189
|
+
)
|
190
|
+
|
191
|
+
exclude_fields = models.BooleanField(
|
192
|
+
verbose_name=_('Exclude Fields'),
|
193
|
+
default=False,
|
194
|
+
help_text=_(
|
195
|
+
'If set, Log Configuration Fields will be excluded from logging. '
|
196
|
+
'Otherwise only configured fields will be logged.'
|
197
|
+
)
|
198
|
+
)
|
199
|
+
|
200
|
+
|
201
|
+
class LogConfigField(models.Model):
|
202
|
+
|
203
|
+
class Meta:
|
204
|
+
verbose_name = _('Log Configuration Field')
|
205
|
+
verbose_name_plural = _('Log Configuration Fields')
|
206
|
+
db_table = 'accrete_log_config_field'
|
207
|
+
ordering = [Lower('field_name')]
|
208
|
+
indexes = [
|
209
|
+
models.Index(fields=['log_config'])
|
210
|
+
]
|
211
|
+
constraints = [
|
212
|
+
models.UniqueConstraint(
|
213
|
+
name='unique_config_field_name',
|
214
|
+
fields=('log_config', 'field_name')
|
215
|
+
)
|
216
|
+
]
|
217
|
+
|
218
|
+
log_config = models.ForeignKey(
|
219
|
+
verbose_name=_('Log Configuration'),
|
220
|
+
to='log.LogConfig',
|
221
|
+
related_name='fields',
|
222
|
+
on_delete=models.CASCADE
|
223
|
+
)
|
224
|
+
|
225
|
+
field_name = models.CharField(
|
226
|
+
verbose_name=_('Field Name'),
|
227
|
+
max_length=255,
|
228
|
+
help_text=_('Name of the field to log')
|
229
|
+
)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from .models import Log
|
2
|
+
from accrete.tenant import get_tenant
|
3
|
+
|
4
|
+
|
5
|
+
def current_log_state(model: str, object_id: int):
|
6
|
+
tenant = get_tenant()
|
7
|
+
tenant_id = tenant and tenant.id or None
|
8
|
+
logs = Log.objects.raw("""
|
9
|
+
SELECT
|
10
|
+
log_value.id,
|
11
|
+
log_value.model,
|
12
|
+
log_value.field,
|
13
|
+
log_value.object_id,
|
14
|
+
log_value.log_date,
|
15
|
+
log_value.old_value_type,
|
16
|
+
log_value.new_value_type,
|
17
|
+
log_value.old_value,
|
18
|
+
log_value.new_value
|
19
|
+
FROM (
|
20
|
+
SELECT model, field, object_id, MAX(log_date) AS log_date
|
21
|
+
FROM accrete_log
|
22
|
+
WHERE
|
23
|
+
model = %s AND
|
24
|
+
object_id = %s AND
|
25
|
+
tenant_id = %s
|
26
|
+
GROUP BY model, field, object_id
|
27
|
+
) log_result
|
28
|
+
JOIN accrete_log log_value ON
|
29
|
+
log_value.model = log_result.model AND
|
30
|
+
log_value.field = log_result.field AND
|
31
|
+
log_value.object_id = log_result.object_id AND
|
32
|
+
log_result.log_date = log_value.log_date;
|
33
|
+
""", [model, object_id, tenant_id])
|
34
|
+
return logs
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from django.db import models
|
4
|
+
|
5
|
+
from accrete.tenant import get_member, get_tenant
|
6
|
+
from accrete.utils.log import log_time
|
7
|
+
from .models import Log, LogConfig
|
8
|
+
from . import helper, queries
|
9
|
+
|
10
|
+
_logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
|
13
|
+
@log_time
|
14
|
+
def create_log(sender, **kwargs):
|
15
|
+
|
16
|
+
def _create_log():
|
17
|
+
member = get_member()
|
18
|
+
user = member and member.user or None
|
19
|
+
object_id = instance.id
|
20
|
+
log_rows = queries.current_log_state(model, object_id)
|
21
|
+
log_state, log_info = helper.log_state_to_dict(log_rows)
|
22
|
+
instance_state = helper.get_instance_state(instance)
|
23
|
+
diff = dict(log_state.items() ^ instance_state.items())
|
24
|
+
logs_to_create = []
|
25
|
+
for field, value in instance_state.items():
|
26
|
+
if field not in diff.keys():
|
27
|
+
continue
|
28
|
+
value_type = helper.internal_type_to_log_type(instance._meta.get_field(field))
|
29
|
+
if value_type is None:
|
30
|
+
continue
|
31
|
+
if value is None:
|
32
|
+
new_value = None
|
33
|
+
else:
|
34
|
+
new_value = str(value)
|
35
|
+
log = Log(
|
36
|
+
model=model,
|
37
|
+
field=field,
|
38
|
+
object_id=instance.id,
|
39
|
+
old_value_type=log_info.get(field, {}).get('new_value_type', ''),
|
40
|
+
old_value=log_state.get(field),
|
41
|
+
new_value_type=helper.internal_type_to_log_type(instance._meta.get_field(field)),
|
42
|
+
new_value=new_value,
|
43
|
+
user=user,
|
44
|
+
tenant=get_tenant()
|
45
|
+
)
|
46
|
+
logs_to_create.append(log)
|
47
|
+
Log.objects.bulk_create(logs_to_create)
|
48
|
+
|
49
|
+
instance: models.Model = kwargs.get('instance')
|
50
|
+
model = f'{instance._meta.app_label}.{instance._meta.model_name}'
|
51
|
+
log_config = LogConfig.objects.filter(model=model).first()
|
52
|
+
if not log_config:
|
53
|
+
return
|
54
|
+
|
55
|
+
try:
|
56
|
+
_create_log()
|
57
|
+
except Exception as e:
|
58
|
+
_logger.exception(e)
|
59
|
+
if log_config.ignore_errors:
|
60
|
+
pass
|
61
|
+
else:
|
62
|
+
raise e
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{% load i18n %}
|
2
|
+
|
3
|
+
{% if form.non_field_errors or form.save_error %}
|
4
|
+
<div class="notification is-danger is-light">
|
5
|
+
{{ form.non_field_errors }}
|
6
|
+
{% if form.save_error %}
|
7
|
+
<p>{{ form.save_error }}</p>
|
8
|
+
<span>{% translate 'Error ID' %}: {{ form.save_error_id }}</span>
|
9
|
+
{% endif %}
|
10
|
+
</div>
|
11
|
+
{% endif %}
|
File without changes
|
@@ -40,3 +40,10 @@ class TenantManager(models.Manager):
|
|
40
40
|
update_conflicts=update_conflicts, update_fields=update_fields,
|
41
41
|
unique_fields=unique_fields
|
42
42
|
)
|
43
|
+
|
44
|
+
|
45
|
+
class MemberManager(TenantManager):
|
46
|
+
|
47
|
+
def get_queryset(self):
|
48
|
+
queryset = super().get_queryset().select_related('tenant', 'user')
|
49
|
+
return queryset
|