django-pfx 1.7.6.dev37__tar.gz → 1.7.6.dev39__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.dev37 → django_pfx-1.7.6.dev39}/PKG-INFO +3 -1
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/PKG-INFO +3 -1
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/SOURCES.txt +1 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/requires.txt +3 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/scm_file_list.json +1 -0
- django_pfx-1.7.6.dev39/django_pfx.egg-info/scm_version.json +8 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/testing.md +36 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/test.py +127 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/requirements.txt +1 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/setup.cfg +1 -0
- django_pfx-1.7.6.dev39/tests/tests/test_table_file_helpers.py +144 -0
- django_pfx-1.7.6.dev37/django_pfx.egg-info/scm_version.json +0 -8
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/.gitignore +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/.gitlab-ci.yml +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/.pre-commit-config.yaml +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/LICENSE +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/MANIFEST.in +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/README.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/dependency_links.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/django_pfx.egg-info/top_level.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/Makefile +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/conf.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/index.rst +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/api.views.rst +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/authentication.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/decorator.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/generate_openapi.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/getting_started.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/internationalisation.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/model.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/pfx_views.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/profiling.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/settings.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/doc/source/user_jobs.md +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/img/pfx.png +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/img/pfx.svg +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/make_messages +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/manage.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/apps.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/email_backend/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/email_backend/memory_email_backend.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/email_backend/q_mailjet_email_backend.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/exceptions.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/mailjet/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/mailjet/mailjet.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/mailjet/message_result.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0002_alter_email_headers.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0003_alter_email_options.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0004_alter_email_mail_from.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0005_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0006_alter_email_attachments.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/models/email.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/providers/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/providers/email_django_q_executor.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/shortcuts.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/tasks.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/templates/emails/base_template.html +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/templates/emails/base_template.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/templates/emails/base_template_subject.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/test.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/views/email_rest_view.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/apidoc/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/apidoc/parameters.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/apidoc/schema.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/apidoc/tags.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/apps.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/decorator/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/decorator/rest.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/default_settings.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/exceptions.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/decimal_field.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/media_field.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/rich_text_field.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/http/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/http/json_response.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/profile.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/authenticator.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/base.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/email.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/legacy.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/mfa/sms.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/authentication.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/locale.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/profiling.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/request_too_big_middleware.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/middleware/ws_cookie_authentication_middleware.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0005_mfadevice_mfadevice_mfa_device_unique_backend.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0006_alter_pfxuser_managers.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0007_alter_pfxuser_options.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/0008_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/attachment_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/cache_mixins.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/login_ban.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/mfa_device.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/mfa_user_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/not_null_fields.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/ordered_model_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/pfx_models.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/pfx_user.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/serializers/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/serializers/json.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/settings.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/shortcuts.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/sms/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/sms/backends/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/sms/backends/base.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/sms/backends/console.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/sms/backends/memory.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/storage/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/storage/exceptions.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/storage/local_storage.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/storage/s3_storage.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/version_check.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/authentication_views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/fields.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/filters_views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/locale_views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/mfa_authentication_views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/date_format.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/groups.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/list_count.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/list_items.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/list_order.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/list_search.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/views/rest_views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/xml_test_runner.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/apps.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0002_alter_userjob_options_alter_userjob_auto_queued_and_more.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0003_clean_scheduled_tasks.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0004_userjob_summary_url.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0005_swappable_user_job.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/0006_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/models/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/models/user_job.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/models/user_job_attachment.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/providers/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/providers/user_job_django_q_executor.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/providers/user_job_websocket_channel_provider.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/tasks.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/views/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/views/user_job_attachment_view.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/views/user_job_view.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/userjobs/views/user_websocket_consumer.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pyproject.toml +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/serve-doc +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/setup.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/apps.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/channel_group_send_calls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/mfa_urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/models.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/common.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/basic_api_errors.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/basic_api_test.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/mfa_test_utils.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/parallel_scenarios.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_api_doc.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_api_doc_search.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_body_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_cache.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_client.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_emails_email_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_emails_email_model.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_emails_q_mailjet_email_backend.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_emails_send_email_message.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_emails_test_tools.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_choices.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_date.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_decimal.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_help_text.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_minutes_duration.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_one2many.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_rich_text.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_fields_time.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_filters.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_locale_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_mfa_legacy.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_mfa_login_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_mfa_setup_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_perm_tests.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_permissions.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_perms_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_post_migrate_groups_update.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_profiling_middleware.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_settings.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_shortcuts.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_test_runner.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_timezone_middleware.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_tools.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_user_job_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_user_job_messages.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_user_job_model.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_user_queryset.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_user_websocket.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_version_check.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_view_decorators.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_view_fields.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/tests/test_ws_cookie_middleware.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests/views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/common.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_base_user/views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/models.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/common.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user/views.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/migrations/0002_lowercase_verbose_names.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/models.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/providers.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/scope.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/common.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/tests/test_user_job.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_custom_user_job/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/migrations/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/models.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/ci.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/common.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/dev.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/settings/dev_default.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/tests/__init__.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/tests/test_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/tests_user_email_login/urls.py +0 -0
- {django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/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.dev39
|
|
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
|
|
@@ -41,6 +41,8 @@ Requires-Dist: pyotp>=2.10.0; extra == "otp"
|
|
|
41
41
|
Provides-Extra: heic-converter
|
|
42
42
|
Requires-Dist: python-magic; extra == "heic-converter"
|
|
43
43
|
Requires-Dist: pillow-heif; extra == "heic-converter"
|
|
44
|
+
Provides-Extra: xlsx
|
|
45
|
+
Requires-Dist: openpyxl; extra == "xlsx"
|
|
44
46
|
Dynamic: license-file
|
|
45
47
|
|
|
46
48
|
# Django PFX
|
|
@@ -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.dev39
|
|
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
|
|
@@ -41,6 +41,8 @@ Requires-Dist: pyotp>=2.10.0; extra == "otp"
|
|
|
41
41
|
Provides-Extra: heic-converter
|
|
42
42
|
Requires-Dist: python-magic; extra == "heic-converter"
|
|
43
43
|
Requires-Dist: pillow-heif; extra == "heic-converter"
|
|
44
|
+
Provides-Extra: xlsx
|
|
45
|
+
Requires-Dist: openpyxl; extra == "xlsx"
|
|
44
46
|
Dynamic: license-file
|
|
45
47
|
|
|
46
48
|
# Django PFX
|
|
@@ -253,6 +253,7 @@ tests/tests/test_post_migrate_groups_update.py
|
|
|
253
253
|
tests/tests/test_profiling_middleware.py
|
|
254
254
|
tests/tests/test_settings.py
|
|
255
255
|
tests/tests/test_shortcuts.py
|
|
256
|
+
tests/tests/test_table_file_helpers.py
|
|
256
257
|
tests/tests/test_test_runner.py
|
|
257
258
|
tests/tests/test_timezone_middleware.py
|
|
258
259
|
tests/tests/test_tools.py
|
|
@@ -243,6 +243,7 @@
|
|
|
243
243
|
"tests/tests/test_profiling_middleware.py",
|
|
244
244
|
"tests/tests/test_settings.py",
|
|
245
245
|
"tests/tests/test_shortcuts.py",
|
|
246
|
+
"tests/tests/test_table_file_helpers.py",
|
|
246
247
|
"tests/tests/test_test_runner.py",
|
|
247
248
|
"tests/tests/test_timezone_middleware.py",
|
|
248
249
|
"tests/tests/test_tools.py",
|
|
@@ -430,3 +430,39 @@ class ATestClass(EmailTestMixin, SMSTestMixin, TestCase):
|
|
|
430
430
|
[(to, message)] = self.sms_outbox()
|
|
431
431
|
self.assertEqual(to, '+41791234567')
|
|
432
432
|
```
|
|
433
|
+
|
|
434
|
+
## CSV and Excel files
|
|
435
|
+
|
|
436
|
+
`CSVFileHelper` and `XLSXFileHelper` read back a table file of a test: an
|
|
437
|
+
export, a file attached to a user job, a file to import.
|
|
438
|
+
|
|
439
|
+
```python
|
|
440
|
+
from pfx.pfxcore.test import CSVFileHelper, XLSXFileHelper
|
|
441
|
+
|
|
442
|
+
f = XLSXFileHelper(response) # or CSVFileHelper(response)
|
|
443
|
+
f.header() # ['Name', 'Birth']
|
|
444
|
+
f.dicts() # [{'Name': 'Alice', 'Birth': datetime(…)}, …]
|
|
445
|
+
f.lines()[0][f.column('Name')] # 'Alice'
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
The file can be given as bytes, a string (its content), a `Path`, an HTTP
|
|
449
|
+
response (streamed or not),
|
|
450
|
+
an iterable of chunks, or the value of a `MediaField` on the local storage
|
|
451
|
+
(`XLSXFileHelper(job.attachments.get().file)`).
|
|
452
|
+
|
|
453
|
+
- `header=2`: the number of the line of the headers, for a file with a title
|
|
454
|
+
above them. The lines after it are the data.
|
|
455
|
+
- `header()`, `lines()`, `dicts()`: the headers, the data as lists, the data
|
|
456
|
+
as dicts by header. `line(n)` and `line_dict(n)` count from 0, the first
|
|
457
|
+
line of the file; `len()` counts every line.
|
|
458
|
+
- `column(title)`: the index of a column.
|
|
459
|
+
- `write_file(path)` and `pretty_print()`: to look at the file while writing a
|
|
460
|
+
test.
|
|
461
|
+
|
|
462
|
+
`CSVFileHelper(data, delimiter=';', encoding='utf-8-sig')` reads the CSV of a
|
|
463
|
+
French Excel; its values are strings.
|
|
464
|
+
|
|
465
|
+
`XLSXFileHelper(data, sheet='Totals')` reads a sheet by name or by index, the
|
|
466
|
+
active one by default. Its values keep their type (numbers, dates), and
|
|
467
|
+
`workbook` and `sheet` give the formats and the styles. It needs
|
|
468
|
+
[openpyxl](https://openpyxl.readthedocs.io/): install `django-pfx[xlsx]`.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import copy
|
|
2
|
+
import csv
|
|
3
|
+
import io
|
|
2
4
|
import json
|
|
3
5
|
import logging
|
|
4
6
|
import re
|
|
@@ -6,6 +8,7 @@ import traceback
|
|
|
6
8
|
from functools import reduce
|
|
7
9
|
from http.cookies import SimpleCookie
|
|
8
10
|
from json import JSONDecodeError
|
|
11
|
+
from pathlib import Path
|
|
9
12
|
|
|
10
13
|
from django.apps import apps
|
|
11
14
|
from django.db import transaction
|
|
@@ -327,6 +330,130 @@ class TestPermsAssertMixin(TestAssertMixin):
|
|
|
327
330
|
self.assertPerms(**perms)
|
|
328
331
|
|
|
329
332
|
|
|
333
|
+
def file_content(data):
|
|
334
|
+
"""The bytes of a file given to a test.
|
|
335
|
+
|
|
336
|
+
``data`` can be bytes, a string, a ``Path``, an HTTP response (streamed
|
|
337
|
+
or not), an iterable of chunks, or the value of a ``MediaField`` on the
|
|
338
|
+
local storage, such as the attachment of a user job.
|
|
339
|
+
"""
|
|
340
|
+
if isinstance(data, bytes):
|
|
341
|
+
return data
|
|
342
|
+
if isinstance(data, Path):
|
|
343
|
+
return data.read_bytes()
|
|
344
|
+
if isinstance(data, str):
|
|
345
|
+
return data.encode()
|
|
346
|
+
if isinstance(data, dict):
|
|
347
|
+
return Path(settings.STORAGE_LOCAL_ROOT, data['key']).read_bytes()
|
|
348
|
+
if hasattr(data, 'streaming_content'):
|
|
349
|
+
data = data.streaming_content
|
|
350
|
+
elif hasattr(data, 'content'):
|
|
351
|
+
return data.content
|
|
352
|
+
return b"".join(
|
|
353
|
+
chunk.encode() if isinstance(chunk, str) else chunk
|
|
354
|
+
for chunk in data)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
class TableFileResponseHelper:
|
|
358
|
+
"""A table file of a test, read back as rows of values.
|
|
359
|
+
|
|
360
|
+
``header`` is the number of the line of the headers, the first by
|
|
361
|
+
default: the lines after it are the data. :meth:`line` counts from 0,
|
|
362
|
+
the first line of the file.
|
|
363
|
+
"""
|
|
364
|
+
|
|
365
|
+
def __init__(self, data, header=1):
|
|
366
|
+
self.content = file_content(data)
|
|
367
|
+
self.header_index = header - 1
|
|
368
|
+
self.rows = self.read_rows()
|
|
369
|
+
|
|
370
|
+
def read_rows(self):
|
|
371
|
+
raise NotImplementedError # pragma: no cover
|
|
372
|
+
|
|
373
|
+
def write_file(self, path):
|
|
374
|
+
"""Write the file, to open it while writing a test."""
|
|
375
|
+
Path(path).write_bytes(self.content)
|
|
376
|
+
|
|
377
|
+
def pretty_print(self):
|
|
378
|
+
"""Print the rows as a table, to read them while writing a test."""
|
|
379
|
+
cells = [
|
|
380
|
+
['' if v is None else str(v) for v in row] for row in self.rows]
|
|
381
|
+
widths = [
|
|
382
|
+
max(len(row[i]) for row in cells if i < len(row))
|
|
383
|
+
for i in range(max((len(row) for row in cells), default=0))]
|
|
384
|
+
print()
|
|
385
|
+
for row in cells:
|
|
386
|
+
print(' '.join(v.ljust(w) for v, w in zip(row, widths)).rstrip())
|
|
387
|
+
|
|
388
|
+
def header(self):
|
|
389
|
+
return self.rows[self.header_index]
|
|
390
|
+
|
|
391
|
+
def line(self, n):
|
|
392
|
+
return self.rows[n]
|
|
393
|
+
|
|
394
|
+
def len(self):
|
|
395
|
+
return len(self.rows)
|
|
396
|
+
|
|
397
|
+
def lines(self):
|
|
398
|
+
"""The rows after the headers."""
|
|
399
|
+
return self.rows[self.header_index + 1:]
|
|
400
|
+
|
|
401
|
+
def column(self, title):
|
|
402
|
+
"""The index of the column ``title``."""
|
|
403
|
+
return self.header().index(title)
|
|
404
|
+
|
|
405
|
+
def line_dict(self, n):
|
|
406
|
+
"""The line ``n`` by header."""
|
|
407
|
+
return dict(zip(self.header(), self.line(n)))
|
|
408
|
+
|
|
409
|
+
def dicts(self):
|
|
410
|
+
"""The rows after the headers, by header."""
|
|
411
|
+
return [dict(zip(self.header(), row)) for row in self.lines()]
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
class CSVFileHelper(TableFileResponseHelper):
|
|
415
|
+
"""A CSV file of a test; the values are strings."""
|
|
416
|
+
|
|
417
|
+
def __init__(self, data, header=1, delimiter=',', encoding='utf-8-sig'):
|
|
418
|
+
self.delimiter = delimiter
|
|
419
|
+
self.encoding = encoding
|
|
420
|
+
super().__init__(data, header)
|
|
421
|
+
|
|
422
|
+
def read_rows(self):
|
|
423
|
+
return list(csv.reader(
|
|
424
|
+
io.StringIO(self.content.decode(self.encoding)),
|
|
425
|
+
delimiter=self.delimiter))
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class XLSXFileHelper(TableFileResponseHelper):
|
|
429
|
+
"""An Excel file of a test, read with openpyxl.
|
|
430
|
+
|
|
431
|
+
``sheet`` is the name or the index of the sheet read, the active one
|
|
432
|
+
by default. The values keep their type (numbers, dates); ``workbook``
|
|
433
|
+
and ``sheet`` give the formats and the styles.
|
|
434
|
+
"""
|
|
435
|
+
|
|
436
|
+
def __init__(self, data, header=1, sheet=None):
|
|
437
|
+
self.sheet_name = sheet
|
|
438
|
+
super().__init__(data, header)
|
|
439
|
+
|
|
440
|
+
def read_rows(self):
|
|
441
|
+
try:
|
|
442
|
+
import openpyxl
|
|
443
|
+
except ImportError: # pragma: no cover
|
|
444
|
+
raise ImportError(
|
|
445
|
+
"XLSXFileHelper needs openpyxl: install django-pfx[xlsx].")
|
|
446
|
+
|
|
447
|
+
self.workbook = openpyxl.load_workbook(io.BytesIO(self.content))
|
|
448
|
+
if self.sheet_name is None:
|
|
449
|
+
self.sheet = self.workbook.active
|
|
450
|
+
elif isinstance(self.sheet_name, int):
|
|
451
|
+
self.sheet = self.workbook.worksheets[self.sheet_name]
|
|
452
|
+
else:
|
|
453
|
+
self.sheet = self.workbook[self.sheet_name]
|
|
454
|
+
return [list(row) for row in self.sheet.iter_rows(values_only=True)]
|
|
455
|
+
|
|
456
|
+
|
|
330
457
|
class MockBoto3Client:
|
|
331
458
|
def generate_presigned_url(self, *args, **kwargs):
|
|
332
459
|
params = kwargs.get('Params', {})
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
from contextlib import redirect_stdout
|
|
5
|
+
from datetime import date
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from django.http import HttpResponse, StreamingHttpResponse
|
|
9
|
+
from django.test import SimpleTestCase, override_settings
|
|
10
|
+
|
|
11
|
+
from openpyxl import Workbook
|
|
12
|
+
|
|
13
|
+
from pfx.pfxcore.test import CSVFileHelper, XLSXFileHelper
|
|
14
|
+
|
|
15
|
+
CSV = "Name,Age\nAlice,30\nBob,\n"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def xlsx(*sheets):
|
|
19
|
+
"""An Excel file of `sheets`, (title, rows) pairs."""
|
|
20
|
+
workbook = Workbook()
|
|
21
|
+
workbook.remove(workbook.active)
|
|
22
|
+
for title, rows in sheets:
|
|
23
|
+
sheet = workbook.create_sheet(title)
|
|
24
|
+
for row in rows:
|
|
25
|
+
sheet.append(row)
|
|
26
|
+
output = io.BytesIO()
|
|
27
|
+
workbook.save(output)
|
|
28
|
+
return output.getvalue()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
PEOPLE = [['Name', 'Birth'], ['Alice', date(1990, 5, 1)], ['Bob', None]]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TestCSVFileHelper(SimpleTestCase):
|
|
35
|
+
def test_the_sources_of_a_file(self):
|
|
36
|
+
"""Bytes, a string, a response, a streamed one, chunks of text."""
|
|
37
|
+
for data in [
|
|
38
|
+
CSV.encode(), CSV, HttpResponse(CSV),
|
|
39
|
+
StreamingHttpResponse(iter([CSV[:10], CSV[10:]])),
|
|
40
|
+
[CSV[:10].encode(), CSV[10:].encode()]]:
|
|
41
|
+
with self.subTest(data=type(data).__name__):
|
|
42
|
+
f = CSVFileHelper(data)
|
|
43
|
+
self.assertEqual(f.header(), ['Name', 'Age'])
|
|
44
|
+
self.assertEqual(f.len(), 3)
|
|
45
|
+
|
|
46
|
+
def test_lines(self):
|
|
47
|
+
"""`line` counts from the headers, `lines` and `dicts` are the data;
|
|
48
|
+
a CSV value is a string."""
|
|
49
|
+
f = CSVFileHelper(CSV)
|
|
50
|
+
|
|
51
|
+
self.assertEqual(f.line(1), ['Alice', '30'])
|
|
52
|
+
self.assertEqual(f.lines(), [['Alice', '30'], ['Bob', '']])
|
|
53
|
+
self.assertEqual(f.column('Age'), 1)
|
|
54
|
+
self.assertEqual(f.line_dict(2), {'Name': 'Bob', 'Age': ''})
|
|
55
|
+
self.assertEqual(
|
|
56
|
+
f.dicts(),
|
|
57
|
+
[{'Name': 'Alice', 'Age': '30'}, {'Name': 'Bob', 'Age': ''}])
|
|
58
|
+
|
|
59
|
+
def test_a_french_excel_csv(self):
|
|
60
|
+
"""Semicolons, and the byte order mark Excel writes."""
|
|
61
|
+
f = CSVFileHelper(
|
|
62
|
+
"Nom;Âge\nAlice;30\n".encode(), delimiter=';')
|
|
63
|
+
|
|
64
|
+
self.assertEqual(f.dicts(), [{'Nom': 'Alice', 'Âge': '30'}])
|
|
65
|
+
|
|
66
|
+
def test_headers_below_a_title(self):
|
|
67
|
+
f = CSVFileHelper("Report\nName,Age\nAlice,30\n", header=2)
|
|
68
|
+
|
|
69
|
+
self.assertEqual(f.header(), ['Name', 'Age'])
|
|
70
|
+
self.assertEqual(f.dicts(), [{'Name': 'Alice', 'Age': '30'}])
|
|
71
|
+
|
|
72
|
+
def test_unknown_column(self):
|
|
73
|
+
with self.assertRaises(ValueError):
|
|
74
|
+
CSVFileHelper(CSV).column('Size')
|
|
75
|
+
|
|
76
|
+
def test_a_path(self):
|
|
77
|
+
"""A Path is a file to read; a string is the content itself."""
|
|
78
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
79
|
+
path = Path(tmp, 'file.csv')
|
|
80
|
+
path.write_text(CSV)
|
|
81
|
+
|
|
82
|
+
self.assertEqual(CSVFileHelper(path).len(), 3)
|
|
83
|
+
|
|
84
|
+
def test_write_file_and_pretty_print(self):
|
|
85
|
+
f = CSVFileHelper(CSV)
|
|
86
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
87
|
+
path = os.path.join(tmp, 'file.csv')
|
|
88
|
+
f.write_file(path)
|
|
89
|
+
with open(path, 'rb') as written:
|
|
90
|
+
self.assertEqual(written.read(), CSV.encode())
|
|
91
|
+
|
|
92
|
+
out = io.StringIO()
|
|
93
|
+
with redirect_stdout(out):
|
|
94
|
+
f.pretty_print()
|
|
95
|
+
self.assertEqual(
|
|
96
|
+
out.getvalue(), "\nName Age\nAlice 30\nBob\n")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class TestXLSXFileHelper(SimpleTestCase):
|
|
100
|
+
def test_values_keep_their_type(self):
|
|
101
|
+
"""A date is a datetime, an empty cell None."""
|
|
102
|
+
f = XLSXFileHelper(xlsx(('People', PEOPLE)))
|
|
103
|
+
|
|
104
|
+
self.assertEqual(f.header(), ['Name', 'Birth'])
|
|
105
|
+
self.assertEqual(f.line_dict(1)['Birth'].date(), date(1990, 5, 1))
|
|
106
|
+
self.assertEqual(f.dicts()[1], {'Name': 'Bob', 'Birth': None})
|
|
107
|
+
self.assertEqual(f.len(), 3)
|
|
108
|
+
self.assertEqual(f.column('Birth'), 1)
|
|
109
|
+
|
|
110
|
+
def test_the_sheet_read(self):
|
|
111
|
+
"""The active one by default, else by name or by index; the sheet
|
|
112
|
+
is there for the formats and the styles."""
|
|
113
|
+
content = xlsx(('People', PEOPLE), ('Totals', [['Total'], [2]]))
|
|
114
|
+
|
|
115
|
+
self.assertEqual(XLSXFileHelper(content).header(), ['Name', 'Birth'])
|
|
116
|
+
f = XLSXFileHelper(content, sheet='Totals')
|
|
117
|
+
self.assertEqual(f.dicts(), [{'Total': 2}])
|
|
118
|
+
self.assertEqual(f.sheet.title, 'Totals')
|
|
119
|
+
self.assertEqual(
|
|
120
|
+
XLSXFileHelper(content, sheet=1).header(), ['Total'])
|
|
121
|
+
|
|
122
|
+
def test_a_response(self):
|
|
123
|
+
f = XLSXFileHelper(StreamingHttpResponse(
|
|
124
|
+
iter([xlsx(('People', PEOPLE))])))
|
|
125
|
+
|
|
126
|
+
self.assertEqual(f.lines()[0][0], 'Alice')
|
|
127
|
+
|
|
128
|
+
def test_headers_below_a_title(self):
|
|
129
|
+
f = XLSXFileHelper(
|
|
130
|
+
xlsx(('Report', [['Report 2026'], *PEOPLE])), header=2)
|
|
131
|
+
|
|
132
|
+
self.assertEqual(f.header(), ['Name', 'Birth'])
|
|
133
|
+
self.assertEqual(len(f.dicts()), 2)
|
|
134
|
+
|
|
135
|
+
def test_a_file_of_the_local_storage(self):
|
|
136
|
+
"""The value of a MediaField, such as the attachment of a job."""
|
|
137
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
138
|
+
with open(os.path.join(tmp, 'export.xlsx'), 'wb') as f:
|
|
139
|
+
f.write(xlsx(('People', PEOPLE)))
|
|
140
|
+
with override_settings(STORAGE_LOCAL_ROOT=tmp):
|
|
141
|
+
helper = XLSXFileHelper(
|
|
142
|
+
{'key': 'export.xlsx', 'name': 'export.xlsx'})
|
|
143
|
+
|
|
144
|
+
self.assertEqual(helper.header(), ['Name', 'Birth'])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/email_backend/memory_email_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/locale/fr/LC_MESSAGES/django.mo
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/locale/fr/LC_MESSAGES/django.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0002_alter_email_headers.py
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/migrations/0003_alter_email_options.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/providers/email_django_q_executor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/templates/emails/base_template.html
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/emails/templates/emails/base_template.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/fields/minutes_duration_field.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po
RENAMED
|
File without changes
|
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/__init__.py
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/makeapidoc.py
RENAMED
|
File without changes
|
{django_pfx-1.7.6.dev37 → django_pfx-1.7.6.dev39}/pfx/pfxcore/management/commands/profile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|