django-pfx 1.7.6.dev41__tar.gz → 1.7.6.dev45__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.
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/PKG-INFO +1 -1
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/PKG-INFO +1 -1
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/SOURCES.txt +2 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/scm_file_list.json +2 -0
- django_pfx-1.7.6.dev45/django_pfx.egg-info/scm_version.json +8 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/api.views.rst +3 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/model.md +46 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/media_field.py +25 -12
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +2 -2
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/pfx_models.py +41 -14
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/test.py +16 -1
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/locale/fr/LC_MESSAGES/django.po +3 -3
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/migrations/0001_initial.py +9 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/models.py +13 -1
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/__init__.py +2 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/basic_api_test.py +48 -16
- django_pfx-1.7.6.dev45/tests/tests/test_fields_media_local.py +295 -0
- django_pfx-1.7.6.dev45/tests/tests/test_fields_media_s3.py +76 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_table_file_helpers.py +1 -2
- django_pfx-1.7.6.dev41/django_pfx.egg-info/scm_version.json +0 -8
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/.gitignore +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/.gitlab-ci.yml +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/.pre-commit-config.yaml +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/LICENSE +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/MANIFEST.in +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/README.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/dependency_links.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/requires.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/top_level.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/Makefile +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/conf.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/index.rst +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/authentication.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/decorator.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/generate_openapi.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/getting_started.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/internationalisation.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/pfx_views.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/profiling.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/settings.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/testing.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/doc/source/user_jobs.md +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/img/pfx.png +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/img/pfx.svg +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/make_messages +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/manage.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/apps.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/memory_email_backend.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/q_mailjet_email_backend.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/exceptions.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/mailjet.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/message_result.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0002_alter_email_headers.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0003_alter_email_options.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0004_alter_email_mail_from.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0005_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0006_alter_email_attachments.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/models/email.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/providers/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/providers/email_django_q_executor.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/shortcuts.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/tasks.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template.html +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template_subject.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/test.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/emails/views/email_rest_view.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/parameters.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/schema.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/tags.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apps.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/decorator/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/decorator/rest.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/default_settings.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/exceptions.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/decimal_field.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/rich_text_field.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/http/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/http/json_response.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/profile.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/authenticator.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/base.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/email.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/legacy.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/sms.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/authentication.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/locale.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/profiling.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/request_too_big_middleware.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/ws_cookie_authentication_middleware.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0005_mfadevice_mfadevice_mfa_device_unique_backend.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0006_alter_pfxuser_managers.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0007_alter_pfxuser_options.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0008_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/attachment_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/cache_mixins.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/login_ban.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/mfa_device.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/mfa_user_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/not_null_fields.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/ordered_model_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/pfx_user.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/serializers/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/serializers/json.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/settings.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/shortcuts.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/base.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/console.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/memory.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/exceptions.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/local_storage.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/s3_storage.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/version_check.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/authentication_views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/fields.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/filters_views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/locale_views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/mfa_authentication_views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/date_format.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/groups.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_count.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_items.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_order.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_search.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/rest_views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/xml_test_runner.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/apps.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0002_alter_userjob_options_alter_userjob_auto_queued_and_more.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0003_clean_scheduled_tasks.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0004_userjob_summary_url.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0005_swappable_user_job.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0006_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/user_job.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/user_job_attachment.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/user_job_django_q_executor.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/user_job_websocket_channel_provider.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/tasks.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_job_attachment_view.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_job_view.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_websocket_consumer.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pyproject.toml +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/requirements.txt +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/serve-doc +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/setup.cfg +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/setup.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/apps.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/channel_group_send_calls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/mfa_urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/common.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/basic_api_errors.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/mfa_test_utils.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/parallel_scenarios.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_api_doc.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_api_doc_search.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_body_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_cache.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_client.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_email_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_email_model.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_q_mailjet_email_backend.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_send_email_message.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_test_tools.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_choices.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_date.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_decimal.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_help_text.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_minutes_duration.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_one2many.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_rich_text.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_time.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_filters.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_locale_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_legacy.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_login_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_setup_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_perm_tests.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_permissions.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_perms_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_post_migrate_groups_update.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_profiling_middleware.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_settings.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_shortcuts.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_test_runner.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_timezone_middleware.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_tools.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_messages.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_model.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_user_queryset.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_user_websocket.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_version_check.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_view_decorators.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_view_fields.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/tests/test_ws_cookie_middleware.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests/views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/common.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_base_user/views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/models.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/common.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user/views.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/0002_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/models.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/providers.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/scope.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/common.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/tests/test_user_job.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_custom_user_job/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/models.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/common.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/urls.py +0 -0
- {django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/tests_user_email_login/views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.7.6.
|
|
3
|
+
Version: 1.7.6.dev45
|
|
4
4
|
Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.7.6.
|
|
3
|
+
Version: 1.7.6.dev45
|
|
4
4
|
Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
@@ -236,6 +236,8 @@ tests/tests/test_fields_choices.py
|
|
|
236
236
|
tests/tests/test_fields_date.py
|
|
237
237
|
tests/tests/test_fields_decimal.py
|
|
238
238
|
tests/tests/test_fields_help_text.py
|
|
239
|
+
tests/tests/test_fields_media_local.py
|
|
240
|
+
tests/tests/test_fields_media_s3.py
|
|
239
241
|
tests/tests/test_fields_minutes_duration.py
|
|
240
242
|
tests/tests/test_fields_one2many.py
|
|
241
243
|
tests/tests/test_fields_rich_text.py
|
|
@@ -226,6 +226,8 @@
|
|
|
226
226
|
"tests/tests/test_fields_date.py",
|
|
227
227
|
"tests/tests/test_fields_decimal.py",
|
|
228
228
|
"tests/tests/test_fields_help_text.py",
|
|
229
|
+
"tests/tests/test_fields_media_local.py",
|
|
230
|
+
"tests/tests/test_fields_media_s3.py",
|
|
229
231
|
"tests/tests/test_fields_minutes_duration.py",
|
|
230
232
|
"tests/tests/test_fields_one2many.py",
|
|
231
233
|
"tests/tests/test_fields_rich_text.py",
|
|
@@ -102,6 +102,52 @@ Which give the following result on the book service :
|
|
|
102
102
|
}
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
## UniqueConstraint
|
|
106
|
+
|
|
107
|
+
`pfx.pfxcore.models.UniqueConstraint` extends the Django constraint
|
|
108
|
+
to give a better validation error to the [PFX views](./pfx_views.md),
|
|
109
|
+
which return it in their `422` response. It takes two optional
|
|
110
|
+
parameters:
|
|
111
|
+
|
|
112
|
+
* `message`: the error message, formatted with the values of the
|
|
113
|
+
constraint fields. It requires a model inheriting `PFXModelMixin`
|
|
114
|
+
and applies to a constraint on `fields` only.
|
|
115
|
+
* `violation_error_field`: the field to report the error under.
|
|
116
|
+
Without it, Django reports the error globally (`__all__`) as soon as
|
|
117
|
+
the constraint is made of several fields or of expressions.
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from django.db import models
|
|
121
|
+
from django.db.models.functions import Lower
|
|
122
|
+
from pfx.pfxcore.models import PFXModelMixin, UniqueConstraint
|
|
123
|
+
|
|
124
|
+
class Book(PFXModelMixin, models.Model):
|
|
125
|
+
name = models.CharField("Name", max_length=100)
|
|
126
|
+
author = models.ForeignKey(
|
|
127
|
+
'tests.Author', on_delete=models.RESTRICT,
|
|
128
|
+
related_name='books', verbose_name="Author")
|
|
129
|
+
|
|
130
|
+
class Meta:
|
|
131
|
+
constraints = [
|
|
132
|
+
UniqueConstraint(
|
|
133
|
+
'author', Lower('name'),
|
|
134
|
+
name='book_unique_author_and_name',
|
|
135
|
+
violation_error_message=(
|
|
136
|
+
"This name is already used for this author."),
|
|
137
|
+
violation_error_field='name')]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
A duplicate name then returns:
|
|
141
|
+
```python
|
|
142
|
+
{
|
|
143
|
+
"name": ["This name is already used for this author."]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`violation_error_field` changes the validation only: from Django 5.2,
|
|
148
|
+
changing it generates an `AlterConstraint` migration, without any
|
|
149
|
+
change to the database.
|
|
150
|
+
|
|
105
151
|
## Not null char fields
|
|
106
152
|
|
|
107
153
|
To avoid storing a mixture of empty strings and `null` values, while automatically
|
|
@@ -6,8 +6,8 @@ from importlib import import_module
|
|
|
6
6
|
from urllib.parse import unquote_to_bytes
|
|
7
7
|
|
|
8
8
|
from django.core.exceptions import ValidationError
|
|
9
|
-
from django.db import models
|
|
10
|
-
from django.db.models.signals import
|
|
9
|
+
from django.db import models, transaction
|
|
10
|
+
from django.db.models.signals import post_init, post_save, pre_delete
|
|
11
11
|
from django.dispatch import receiver
|
|
12
12
|
|
|
13
13
|
from pfx.pfxcore.shortcuts import settings
|
|
@@ -104,6 +104,12 @@ class MediaField(models.JSONField):
|
|
|
104
104
|
setattr(obj, self.name, self.upload(obj, file, name))
|
|
105
105
|
obj.save(update_fields={self.name})
|
|
106
106
|
|
|
107
|
+
def delete_file(value):
|
|
108
|
+
transaction.on_commit(
|
|
109
|
+
lambda value=value: self.delete(value),
|
|
110
|
+
robust=True,
|
|
111
|
+
)
|
|
112
|
+
|
|
107
113
|
after_save = []
|
|
108
114
|
value = self.value_from_object(obj)
|
|
109
115
|
if isinstance(value, dict):
|
|
@@ -112,10 +118,10 @@ class MediaField(models.JSONField):
|
|
|
112
118
|
else:
|
|
113
119
|
b64 = None
|
|
114
120
|
|
|
115
|
-
db_value = obj
|
|
121
|
+
db_value = getattr(obj, f'_db_{self.name}')
|
|
116
122
|
if db_value and (b64 or not value):
|
|
117
|
-
after_save.append(lambda: self.delete(db_value))
|
|
118
123
|
setattr(obj, self.name, None)
|
|
124
|
+
after_save.append(lambda: delete_file(db_value))
|
|
119
125
|
if b64:
|
|
120
126
|
try:
|
|
121
127
|
file = decode_data_uri(b64)
|
|
@@ -160,21 +166,28 @@ class MediaField(models.JSONField):
|
|
|
160
166
|
return self.storage.delete(value)
|
|
161
167
|
|
|
162
168
|
|
|
163
|
-
# Kept on the instance: the field is shared by every instance of the model.
|
|
164
169
|
@receiver(post_init)
|
|
165
170
|
@receiver(post_save)
|
|
166
|
-
def
|
|
171
|
+
def init_db_value(sender, instance, update_fields=None, **kwargs):
|
|
172
|
+
"""Set the current db value in _db_{field_name} to track changes.
|
|
173
|
+
|
|
174
|
+
_db_{field_name} is the standard naming convention in PFX to track
|
|
175
|
+
current db value (normally done in `__init__()`).
|
|
176
|
+
"""
|
|
167
177
|
for field in sender._meta.fields:
|
|
168
178
|
if isinstance(field, MediaField) and (
|
|
169
179
|
update_fields is None or field.name in update_fields):
|
|
170
|
-
|
|
171
|
-
instance
|
|
172
|
-
instance._media_db_values[field.name] = (
|
|
180
|
+
setattr(
|
|
181
|
+
instance, f'_db_{field.name}',
|
|
173
182
|
field.value_from_object(instance))
|
|
174
183
|
|
|
175
184
|
|
|
176
|
-
@receiver(
|
|
177
|
-
def
|
|
185
|
+
@receiver(pre_delete)
|
|
186
|
+
def pre_delete_media(sender, instance, **kwargs):
|
|
178
187
|
for field in sender._meta.fields:
|
|
179
188
|
if isinstance(field, MediaField) and field.auto_delete:
|
|
180
|
-
field.
|
|
189
|
+
value = field.value_from_object(instance)
|
|
190
|
+
transaction.on_commit(
|
|
191
|
+
lambda field=field, value=value: field.storage.delete(value),
|
|
192
|
+
robust=True,
|
|
193
|
+
)
|
{django_pfx-1.7.6.dev41 → django_pfx-1.7.6.dev45}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po
RENAMED
|
@@ -7,7 +7,7 @@ msgid ""
|
|
|
7
7
|
msgstr ""
|
|
8
8
|
"Project-Id-Version: \n"
|
|
9
9
|
"Report-Msgid-Bugs-To: \n"
|
|
10
|
-
"POT-Creation-Date: 2026-10-
|
|
10
|
+
"POT-Creation-Date: 2026-10-28 14:02+0100\n"
|
|
11
11
|
"PO-Revision-Date: 2021-06-22 23:31+0200\n"
|
|
12
12
|
"Last-Translator: \n"
|
|
13
13
|
"Language-Team: \n"
|
|
@@ -175,7 +175,7 @@ msgstr "MFA forcé"
|
|
|
175
175
|
msgid "sequence"
|
|
176
176
|
msgstr "séquence"
|
|
177
177
|
|
|
178
|
-
#: models/pfx_models.py:
|
|
178
|
+
#: models/pfx_models.py:26
|
|
179
179
|
#, python-format
|
|
180
180
|
msgid "%(model_name)s with this %(field_labels)s already exists."
|
|
181
181
|
msgstr "%(model_name)s avec ce/cette %(field_labels)s existe déjà."
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
from django.core.exceptions import
|
|
4
|
+
from django.core.exceptions import ValidationError
|
|
5
5
|
from django.db import models
|
|
6
6
|
from django.utils.translation import gettext_lazy as _
|
|
7
7
|
|
|
@@ -9,14 +9,42 @@ logger = logging.getLogger(__name__)
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class UniqueConstraint(models.UniqueConstraint):
|
|
12
|
-
|
|
12
|
+
"""A unique constraint with a richer validation error.
|
|
13
|
+
|
|
14
|
+
:param message: The error message, formatted with the values of the
|
|
15
|
+
constraint fields (``%(name)s already exists``)
|
|
16
|
+
:param violation_error_field: The field to report the error under,
|
|
17
|
+
instead of the global errors (``__all__``)
|
|
18
|
+
"""
|
|
19
|
+
non_db_attrs = (
|
|
20
|
+
*getattr(models.UniqueConstraint, 'non_db_attrs', ()),
|
|
21
|
+
'violation_error_field')
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self, *args, message=None, violation_error_field=None, **kwargs):
|
|
13
25
|
self.message = message or _(
|
|
14
26
|
"%(model_name)s with this %(field_labels)s already exists.")
|
|
27
|
+
self.violation_error_field = violation_error_field
|
|
15
28
|
super().__init__(*args, **kwargs)
|
|
16
29
|
|
|
30
|
+
def validate(self, *args, **kwargs):
|
|
31
|
+
try:
|
|
32
|
+
super().validate(*args, **kwargs)
|
|
33
|
+
except ValidationError as e:
|
|
34
|
+
if not self.violation_error_field:
|
|
35
|
+
raise
|
|
36
|
+
raise ValidationError({self.violation_error_field: e})
|
|
37
|
+
|
|
38
|
+
def __eq__(self, other):
|
|
39
|
+
return super().__eq__(other) and (
|
|
40
|
+
self.violation_error_field ==
|
|
41
|
+
getattr(other, 'violation_error_field', None))
|
|
42
|
+
|
|
17
43
|
def deconstruct(self):
|
|
18
44
|
path, args, kwargs = super().deconstruct()
|
|
19
45
|
kwargs['message'] = self.message
|
|
46
|
+
if self.violation_error_field:
|
|
47
|
+
kwargs['violation_error_field'] = self.violation_error_field
|
|
20
48
|
return path, args, kwargs
|
|
21
49
|
|
|
22
50
|
|
|
@@ -85,8 +113,9 @@ class ErrorMessageMixin():
|
|
|
85
113
|
"""A model mixin to improve mode validation errors."""
|
|
86
114
|
|
|
87
115
|
def validate_constraints(self, exclude=None):
|
|
88
|
-
"""Override
|
|
89
|
-
|
|
116
|
+
"""Override validate_constraints to apply the custom message
|
|
117
|
+
of a :class:`UniqueConstraint`, whatever the field its error is
|
|
118
|
+
reported under.
|
|
90
119
|
"""
|
|
91
120
|
def objgetattr(obj, f):
|
|
92
121
|
v = getattr(obj, f)
|
|
@@ -99,11 +128,11 @@ class ErrorMessageMixin():
|
|
|
99
128
|
try:
|
|
100
129
|
return super().validate_constraints(exclude=exclude)
|
|
101
130
|
except ValidationError as e:
|
|
102
|
-
errors =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
131
|
+
errors = {}
|
|
132
|
+
for key, field_errors in e.update_error_dict({}).items():
|
|
133
|
+
for error in field_errors:
|
|
134
|
+
if (isinstance(error, ValidationError) and
|
|
135
|
+
error.code in ('unique', 'unique_together')):
|
|
107
136
|
model = error.params['model_class']
|
|
108
137
|
unique_check = error.params['unique_check']
|
|
109
138
|
unique = next(filter(
|
|
@@ -114,13 +143,11 @@ class ErrorMessageMixin():
|
|
|
114
143
|
params = dict(error.params)
|
|
115
144
|
params.update({
|
|
116
145
|
f: objgetattr(self, f) for f in unique_check})
|
|
117
|
-
|
|
146
|
+
error = ValidationError(
|
|
118
147
|
message=unique.message,
|
|
119
148
|
code=error.code,
|
|
120
|
-
params=params)
|
|
121
|
-
|
|
122
|
-
non_field_errors.append(error)
|
|
123
|
-
errors[NON_FIELD_ERRORS] = non_field_errors
|
|
149
|
+
params=params)
|
|
150
|
+
errors.setdefault(key, []).append(error)
|
|
124
151
|
raise ValidationError(errors)
|
|
125
152
|
|
|
126
153
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import base64
|
|
1
2
|
import copy
|
|
2
3
|
import csv
|
|
3
4
|
import io
|
|
@@ -218,7 +219,6 @@ class APIClient(DjangoClient):
|
|
|
218
219
|
|
|
219
220
|
|
|
220
221
|
class TestAssertMixin:
|
|
221
|
-
|
|
222
222
|
# assert response status code
|
|
223
223
|
def assertRC(self, response, code, msg=None):
|
|
224
224
|
msg = '\n'.join([msg or '', response.formatted()])
|
|
@@ -291,6 +291,21 @@ class TestAssertMixin:
|
|
|
291
291
|
return self.assertNotIn(
|
|
292
292
|
element, self.get_val(src, key, msg=msg), msg=msg)
|
|
293
293
|
|
|
294
|
+
def as_data_url(self, content="Test content"):
|
|
295
|
+
if isinstance(content, str):
|
|
296
|
+
content = content.encode()
|
|
297
|
+
b64 = base64.b64encode(content).decode('ascii')
|
|
298
|
+
return f"data:text/plain;charset=utf-8;base64,{b64}"
|
|
299
|
+
|
|
300
|
+
@classmethod
|
|
301
|
+
def upload_file(
|
|
302
|
+
cls, obj, field='file', file_name='test.txt',
|
|
303
|
+
content="A test file content.", **kw):
|
|
304
|
+
if isinstance(content, str):
|
|
305
|
+
content = content.encode()
|
|
306
|
+
return obj.__class__._meta.get_field(field).upload(
|
|
307
|
+
obj, content, file_name)
|
|
308
|
+
|
|
294
309
|
|
|
295
310
|
class TestPermsAssertMixin(TestAssertMixin):
|
|
296
311
|
USER_TESTS = {}
|
|
@@ -8,7 +8,7 @@ msgid ""
|
|
|
8
8
|
msgstr ""
|
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
|
11
|
-
"POT-Creation-Date: 2026-
|
|
11
|
+
"POT-Creation-Date: 2026-10-28 14:02+0100\n"
|
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
@@ -18,11 +18,11 @@ msgstr ""
|
|
|
18
18
|
"Content-Transfer-Encoding: 8bit\n"
|
|
19
19
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
|
20
20
|
|
|
21
|
-
#: models.py:
|
|
21
|
+
#: models.py:58
|
|
22
22
|
msgid "First Name"
|
|
23
23
|
msgstr "Prénom"
|
|
24
24
|
|
|
25
|
-
#: models.py:
|
|
25
|
+
#: models.py:59
|
|
26
26
|
msgid "Last Name"
|
|
27
27
|
msgstr "Nom"
|
|
28
28
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import django.contrib.auth.validators
|
|
5
5
|
import django.db.models.deletion
|
|
6
|
+
import django.db.models.functions.text
|
|
6
7
|
import django.utils.timezone
|
|
7
8
|
from django.db import migrations, models
|
|
8
9
|
|
|
@@ -128,4 +129,12 @@ class Migration(migrations.Migration):
|
|
|
128
129
|
model_name='book',
|
|
129
130
|
constraint=pfx.pfxcore.models.pfx_models.UniqueConstraint(fields=('author', 'name'), message='%(name)s already exists for %(author)s', name='book_unique_author_and_name'),
|
|
130
131
|
),
|
|
132
|
+
migrations.AddConstraint(
|
|
133
|
+
model_name='book',
|
|
134
|
+
constraint=pfx.pfxcore.models.pfx_models.UniqueConstraint(models.F('author'), django.db.models.functions.text.Lower('name'), message='%(model_name)s with this %(field_labels)s already exists.', name='book_unique_author_and_lower_name', violation_error_field='name', violation_error_message='This name is already used for this author.'),
|
|
135
|
+
),
|
|
136
|
+
migrations.AddConstraint(
|
|
137
|
+
model_name='book',
|
|
138
|
+
constraint=pfx.pfxcore.models.pfx_models.UniqueConstraint(fields=('author', 'pages'), message='A book of %(pages)s pages exists for %(author)s', name='book_unique_author_and_pages', violation_error_field='pages'),
|
|
139
|
+
),
|
|
131
140
|
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from django.db.models import Q
|
|
3
|
+
from django.db.models.functions import Lower
|
|
3
4
|
from django.utils.functional import cached_property
|
|
4
5
|
from django.utils.translation import gettext_lazy as _
|
|
5
6
|
|
|
@@ -151,7 +152,18 @@ class Book(CacheDependsMixin, PFXModelMixin, models.Model):
|
|
|
151
152
|
UniqueConstraint(
|
|
152
153
|
fields=['author', 'name'],
|
|
153
154
|
name='book_unique_author_and_name',
|
|
154
|
-
message="%(name)s already exists for %(author)s")
|
|
155
|
+
message="%(name)s already exists for %(author)s"),
|
|
156
|
+
UniqueConstraint(
|
|
157
|
+
'author', Lower('name'),
|
|
158
|
+
name='book_unique_author_and_lower_name',
|
|
159
|
+
violation_error_message=(
|
|
160
|
+
"This name is already used for this author."),
|
|
161
|
+
violation_error_field='name'),
|
|
162
|
+
UniqueConstraint(
|
|
163
|
+
fields=['author', 'pages'],
|
|
164
|
+
name='book_unique_author_and_pages',
|
|
165
|
+
message="A book of %(pages)s pages exists for %(author)s",
|
|
166
|
+
violation_error_field='pages')]
|
|
155
167
|
|
|
156
168
|
def __str__(self):
|
|
157
169
|
return f"{self.name}"
|
|
@@ -17,6 +17,8 @@ from .test_emails_test_tools import (
|
|
|
17
17
|
from .test_fields_choices import TestFieldsChoices
|
|
18
18
|
from .test_fields_date import TestFieldsDate
|
|
19
19
|
from .test_fields_decimal import TestFieldsDecimal
|
|
20
|
+
from .test_fields_media_local import TestFieldsMediaLocal
|
|
21
|
+
from .test_fields_media_s3 import TestFieldsMediaS3
|
|
20
22
|
from .test_fields_minutes_duration import TestFieldsMinutesDuration
|
|
21
23
|
from .test_fields_one2many import TestFieldsOne2Many
|
|
22
24
|
from .test_fields_rich_text import TestFieldsRichText
|
|
@@ -828,11 +828,12 @@ class BasicAPITest(TestAssertMixin, TestCase):
|
|
|
828
828
|
self.assertTrue(Path(f'/tmp/django-pfx-filestore/{key1}').exists())
|
|
829
829
|
|
|
830
830
|
# Replace file
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
831
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
832
|
+
response = self.client.put(f'/api/books/{book_pk}', dict(
|
|
833
|
+
local_file=dict(
|
|
834
|
+
name='test2.txt',
|
|
835
|
+
base64='data:text/plain;charset=utf-8;'
|
|
836
|
+
'base64,TmV3IGNvbnRlbnQ=')))
|
|
836
837
|
self.assertRC(response, 200)
|
|
837
838
|
self.assertNJE(response, 'local_file.key', key1)
|
|
838
839
|
self.assertJE(response, 'local_file.name', 'test2.txt')
|
|
@@ -841,8 +842,9 @@ class BasicAPITest(TestAssertMixin, TestCase):
|
|
|
841
842
|
self.assertTrue(Path(f'/tmp/django-pfx-filestore/{key2}').exists())
|
|
842
843
|
|
|
843
844
|
# Delete file
|
|
844
|
-
|
|
845
|
-
|
|
845
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
846
|
+
response = self.client.put(f'/api/books/{book_pk}', dict(
|
|
847
|
+
local_file=None))
|
|
846
848
|
self.assertRC(response, 200)
|
|
847
849
|
self.assertJE(response, 'local_file', None)
|
|
848
850
|
self.assertFalse(Path(f'/tmp/django-pfx-filestore/{key2}').exists())
|
|
@@ -865,10 +867,11 @@ class BasicAPITest(TestAssertMixin, TestCase):
|
|
|
865
867
|
book.local_file = dict(
|
|
866
868
|
name='new.txt',
|
|
867
869
|
base64='data:text/plain;charset=utf-8;base64,TmV3IGNvbnRlbnQ=')
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
func
|
|
870
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
871
|
+
funcs = Book._meta.get_field('local_file').media_pre_save(book)
|
|
872
|
+
book.save()
|
|
873
|
+
for func in funcs:
|
|
874
|
+
func()
|
|
872
875
|
return book.local_file['key']
|
|
873
876
|
|
|
874
877
|
def test_replace_file_after_loading_another_object(self):
|
|
@@ -1052,6 +1055,34 @@ class BasicAPITest(TestAssertMixin, TestCase):
|
|
|
1052
1055
|
response, '__all__.@0',
|
|
1053
1056
|
'The Hobbit already exists for John Ronald Reuel Tolkien')
|
|
1054
1057
|
|
|
1058
|
+
def test_create_unique_error_field(self):
|
|
1059
|
+
"""A constraint on an expression reports its error globally in
|
|
1060
|
+
Django: `violation_error_field` puts it under the field."""
|
|
1061
|
+
response = self.client.post(
|
|
1062
|
+
'/api/books', dict(
|
|
1063
|
+
name="the hobbit",
|
|
1064
|
+
author=self.author1.pk,
|
|
1065
|
+
pub_date="1937-09-21"))
|
|
1066
|
+
self.assertRC(response, 422)
|
|
1067
|
+
self.assertJE(
|
|
1068
|
+
response, 'name.@0', "This name is already used for this author.")
|
|
1069
|
+
self.assertJENotExists(response, '__all__')
|
|
1070
|
+
|
|
1071
|
+
def test_create_unique_custom_message_error_field(self):
|
|
1072
|
+
"""The custom message still applies to an error reported under a
|
|
1073
|
+
field."""
|
|
1074
|
+
response = self.client.post(
|
|
1075
|
+
'/api/books', dict(
|
|
1076
|
+
name="The End of Eternity",
|
|
1077
|
+
author=self.author3.pk,
|
|
1078
|
+
pub_date="1955-01-01",
|
|
1079
|
+
pages=224))
|
|
1080
|
+
self.assertRC(response, 422)
|
|
1081
|
+
self.assertJE(
|
|
1082
|
+
response, 'pages.@0',
|
|
1083
|
+
'A book of 224 pages exists for Isaac Asimov')
|
|
1084
|
+
self.assertJENotExists(response, '__all__')
|
|
1085
|
+
|
|
1055
1086
|
def test_create_invalid_date(self):
|
|
1056
1087
|
response = self.client.post(
|
|
1057
1088
|
'/api/books', dict(
|
|
@@ -1426,14 +1457,15 @@ class BasicAPITest(TestAssertMixin, TestCase):
|
|
|
1426
1457
|
response, f"http://dragonfly.fake/{key}",
|
|
1427
1458
|
fetch_redirect_response=False)
|
|
1428
1459
|
|
|
1429
|
-
with patch.object(
|
|
1460
|
+
with (patch.object(
|
|
1430
1461
|
MockBoto3Client, 'delete_object',
|
|
1431
|
-
return_value=None) as mock_delete
|
|
1462
|
+
return_value=None) as mock_delete,
|
|
1463
|
+
self.captureOnCommitCallbacks(execute=True)):
|
|
1432
1464
|
response = self.client.delete(
|
|
1433
1465
|
f'/api/books/{self.author1_book1.pk}')
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1466
|
+
mock_delete.assert_called_with(
|
|
1467
|
+
Bucket='dragonfly.fake',
|
|
1468
|
+
Key=key)
|
|
1437
1469
|
|
|
1438
1470
|
def test_annotate_meta_service(self):
|
|
1439
1471
|
response = self.client.get('/api/authors-annotate/meta')
|