django-pfx 1.7.6.dev43__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.
Files changed (332) hide show
  1. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/PKG-INFO +1 -1
  2. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/PKG-INFO +1 -1
  3. django_pfx-1.7.6.dev45/django_pfx.egg-info/scm_version.json +8 -0
  4. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/api.views.rst +3 -0
  5. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/model.md +46 -0
  6. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +2 -2
  7. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/pfx_models.py +41 -14
  8. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/locale/fr/LC_MESSAGES/django.po +3 -3
  9. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/migrations/0001_initial.py +9 -0
  10. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/models.py +13 -1
  11. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/basic_api_test.py +28 -0
  12. django_pfx-1.7.6.dev43/django_pfx.egg-info/scm_version.json +0 -8
  13. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/.gitignore +0 -0
  14. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/.gitlab-ci.yml +0 -0
  15. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/.pre-commit-config.yaml +0 -0
  16. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/LICENSE +0 -0
  17. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/MANIFEST.in +0 -0
  18. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/README.md +0 -0
  19. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/SOURCES.txt +0 -0
  20. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/dependency_links.txt +0 -0
  21. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/requires.txt +0 -0
  22. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/scm_file_list.json +0 -0
  23. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/django_pfx.egg-info/top_level.txt +0 -0
  24. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/Makefile +0 -0
  25. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/conf.py +0 -0
  26. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/index.rst +0 -0
  27. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/authentication.md +0 -0
  28. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/decorator.md +0 -0
  29. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/generate_openapi.md +0 -0
  30. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/getting_started.md +0 -0
  31. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/internationalisation.md +0 -0
  32. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/pfx_views.md +0 -0
  33. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/profiling.md +0 -0
  34. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/settings.md +0 -0
  35. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/testing.md +0 -0
  36. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/doc/source/user_jobs.md +0 -0
  37. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/img/pfx.png +0 -0
  38. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/img/pfx.svg +0 -0
  39. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/make_messages +0 -0
  40. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/manage.py +0 -0
  41. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/__init__.py +0 -0
  42. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/__init__.py +0 -0
  43. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/apps.py +0 -0
  44. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/__init__.py +0 -0
  45. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/memory_email_backend.py +0 -0
  46. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/email_backend/q_mailjet_email_backend.py +0 -0
  47. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/exceptions.py +0 -0
  48. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/locale/fr/LC_MESSAGES/django.mo +0 -0
  49. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/locale/fr/LC_MESSAGES/django.po +0 -0
  50. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/__init__.py +0 -0
  51. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/mailjet.py +0 -0
  52. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/mailjet/message_result.py +0 -0
  53. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0001_initial.py +0 -0
  54. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0002_alter_email_headers.py +0 -0
  55. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0003_alter_email_options.py +0 -0
  56. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0004_alter_email_mail_from.py +0 -0
  57. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0005_lowercase_verbose_names.py +0 -0
  58. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/0006_alter_email_attachments.py +0 -0
  59. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/migrations/__init__.py +0 -0
  60. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/models/__init__.py +0 -0
  61. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/models/email.py +0 -0
  62. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/providers/__init__.py +0 -0
  63. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/providers/email_django_q_executor.py +0 -0
  64. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/shortcuts.py +0 -0
  65. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/tasks.py +0 -0
  66. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template.html +0 -0
  67. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template.txt +0 -0
  68. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/templates/emails/base_template_subject.txt +0 -0
  69. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/test.py +0 -0
  70. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/urls.py +0 -0
  71. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/views/__init__.py +0 -0
  72. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/emails/views/email_rest_view.py +0 -0
  73. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/__init__.py +0 -0
  74. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/__init__.py +0 -0
  75. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/parameters.py +0 -0
  76. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/schema.py +0 -0
  77. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apidoc/tags.py +0 -0
  78. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/apps.py +0 -0
  79. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/decorator/__init__.py +0 -0
  80. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/decorator/rest.py +0 -0
  81. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/default_settings.py +0 -0
  82. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/exceptions.py +0 -0
  83. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/__init__.py +0 -0
  84. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/decimal_field.py +0 -0
  85. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/media_field.py +0 -0
  86. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
  87. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/fields/rich_text_field.py +0 -0
  88. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/http/__init__.py +0 -0
  89. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/http/json_response.py +0 -0
  90. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  91. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/__init__.py +0 -0
  92. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/__init__.py +0 -0
  93. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  94. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/management/commands/profile.py +0 -0
  95. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/__init__.py +0 -0
  96. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/authenticator.py +0 -0
  97. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/base.py +0 -0
  98. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/email.py +0 -0
  99. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/legacy.py +0 -0
  100. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/mfa/sms.py +0 -0
  101. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/__init__.py +0 -0
  102. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/authentication.py +0 -0
  103. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/locale.py +0 -0
  104. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/profiling.py +0 -0
  105. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/request_too_big_middleware.py +0 -0
  106. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/middleware/ws_cookie_authentication_middleware.py +0 -0
  107. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0001_initial.py +0 -0
  108. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
  109. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
  110. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py +0 -0
  111. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0005_mfadevice_mfadevice_mfa_device_unique_backend.py +0 -0
  112. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0006_alter_pfxuser_managers.py +0 -0
  113. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0007_alter_pfxuser_options.py +0 -0
  114. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/0008_lowercase_verbose_names.py +0 -0
  115. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/__init__.py +0 -0
  116. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
  117. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
  118. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/__init__.py +0 -0
  119. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
  120. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/attachment_mixin.py +0 -0
  121. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/cache_mixins.py +0 -0
  122. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/login_ban.py +0 -0
  123. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/mfa_device.py +0 -0
  124. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/mfa_user_mixin.py +0 -0
  125. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/not_null_fields.py +0 -0
  126. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/ordered_model_mixin.py +0 -0
  127. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/pfx_user.py +0 -0
  128. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  129. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/serializers/__init__.py +0 -0
  130. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/serializers/json.py +0 -0
  131. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/settings.py +0 -0
  132. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/shortcuts.py +0 -0
  133. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/__init__.py +0 -0
  134. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/__init__.py +0 -0
  135. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/base.py +0 -0
  136. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/console.py +0 -0
  137. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/sms/backends/memory.py +0 -0
  138. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/__init__.py +0 -0
  139. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/exceptions.py +0 -0
  140. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/local_storage.py +0 -0
  141. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/storage/s3_storage.py +0 -0
  142. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
  143. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
  144. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  145. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  146. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  147. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  148. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/test.py +0 -0
  149. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/urls.py +0 -0
  150. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/version_check.py +0 -0
  151. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/__init__.py +0 -0
  152. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/authentication_views.py +0 -0
  153. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/fields.py +0 -0
  154. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/filters_views.py +0 -0
  155. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/locale_views.py +0 -0
  156. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
  157. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/mfa_authentication_views.py +0 -0
  158. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
  159. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  160. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  161. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/groups.py +0 -0
  162. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  163. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  164. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  165. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  166. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  167. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  168. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  169. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  170. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  171. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset.py +0 -0
  172. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  173. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  174. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  175. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  176. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  177. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/views/rest_views.py +0 -0
  178. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/pfxcore/xml_test_runner.py +0 -0
  179. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/settings/__init__.py +0 -0
  180. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/settings/dev.py +0 -0
  181. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/__init__.py +0 -0
  182. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/apps.py +0 -0
  183. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/locale/fr/LC_MESSAGES/django.mo +0 -0
  184. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/locale/fr/LC_MESSAGES/django.po +0 -0
  185. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0001_initial.py +0 -0
  186. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0002_alter_userjob_options_alter_userjob_auto_queued_and_more.py +0 -0
  187. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0003_clean_scheduled_tasks.py +0 -0
  188. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0004_userjob_summary_url.py +0 -0
  189. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0005_swappable_user_job.py +0 -0
  190. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/0006_lowercase_verbose_names.py +0 -0
  191. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/migrations/__init__.py +0 -0
  192. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/__init__.py +0 -0
  193. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/user_job.py +0 -0
  194. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/models/user_job_attachment.py +0 -0
  195. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/__init__.py +0 -0
  196. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/user_job_django_q_executor.py +0 -0
  197. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/providers/user_job_websocket_channel_provider.py +0 -0
  198. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/tasks.py +0 -0
  199. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/urls.py +0 -0
  200. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/__init__.py +0 -0
  201. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_job_attachment_view.py +0 -0
  202. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_job_view.py +0 -0
  203. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pfx/userjobs/views/user_websocket_consumer.py +0 -0
  204. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/pyproject.toml +0 -0
  205. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/requirements.txt +0 -0
  206. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/serve-doc +0 -0
  207. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/setup.cfg +0 -0
  208. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/setup.py +0 -0
  209. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/__init__.py +0 -0
  210. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/apps.py +0 -0
  211. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/channel_group_send_calls.py +0 -0
  212. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/mfa_urls.py +0 -0
  213. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/migrations/__init__.py +0 -0
  214. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/__init__.py +0 -0
  215. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/ci.py +0 -0
  216. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/common.py +0 -0
  217. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/dev.py +0 -0
  218. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/dev_custom_example.py +0 -0
  219. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/settings/dev_default.py +0 -0
  220. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/__init__.py +0 -0
  221. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/basic_api_errors.py +0 -0
  222. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/mfa_test_utils.py +0 -0
  223. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/parallel_scenarios.py +0 -0
  224. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_api_doc.py +0 -0
  225. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_api_doc_search.py +0 -0
  226. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_auth_api.py +0 -0
  227. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_body_mixin.py +0 -0
  228. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_cache.py +0 -0
  229. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_client.py +0 -0
  230. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_email_api.py +0 -0
  231. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_email_model.py +0 -0
  232. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_q_mailjet_email_backend.py +0 -0
  233. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_send_email_message.py +0 -0
  234. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_emails_test_tools.py +0 -0
  235. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_choices.py +0 -0
  236. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_date.py +0 -0
  237. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_decimal.py +0 -0
  238. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_help_text.py +0 -0
  239. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_media_local.py +0 -0
  240. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_media_s3.py +0 -0
  241. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_minutes_duration.py +0 -0
  242. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_one2many.py +0 -0
  243. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_rich_text.py +0 -0
  244. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_fields_time.py +0 -0
  245. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_filters.py +0 -0
  246. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_locale_api.py +0 -0
  247. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_legacy.py +0 -0
  248. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_login_api.py +0 -0
  249. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_mfa_setup_api.py +0 -0
  250. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
  251. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_perm_tests.py +0 -0
  252. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_permissions.py +0 -0
  253. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_perms_api.py +0 -0
  254. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_post_migrate_groups_update.py +0 -0
  255. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_profiling_middleware.py +0 -0
  256. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_settings.py +0 -0
  257. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_shortcuts.py +0 -0
  258. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_table_file_helpers.py +0 -0
  259. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_test_runner.py +0 -0
  260. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_timezone_middleware.py +0 -0
  261. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_tools.py +0 -0
  262. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_api.py +0 -0
  263. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_messages.py +0 -0
  264. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_user_job_model.py +0 -0
  265. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_user_queryset.py +0 -0
  266. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_user_websocket.py +0 -0
  267. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_verbose_names.py +0 -0
  268. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_version_check.py +0 -0
  269. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_view_decorators.py +0 -0
  270. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_view_fields.py +0 -0
  271. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/tests/test_ws_cookie_middleware.py +0 -0
  272. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/urls.py +0 -0
  273. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests/views.py +0 -0
  274. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/__init__.py +0 -0
  275. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/migrations/__init__.py +0 -0
  276. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/__init__.py +0 -0
  277. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/ci.py +0 -0
  278. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/common.py +0 -0
  279. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev.py +0 -0
  280. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev_custom_example.py +0 -0
  281. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/settings/dev_default.py +0 -0
  282. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/tests/__init__.py +0 -0
  283. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/tests/test_api.py +0 -0
  284. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/tests/test_auth_api.py +0 -0
  285. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/urls.py +0 -0
  286. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_base_user/views.py +0 -0
  287. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/__init__.py +0 -0
  288. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/migrations/0001_initial.py +0 -0
  289. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/migrations/__init__.py +0 -0
  290. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/models.py +0 -0
  291. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/__init__.py +0 -0
  292. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/ci.py +0 -0
  293. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/common.py +0 -0
  294. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev.py +0 -0
  295. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev_custom_example.py +0 -0
  296. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/settings/dev_default.py +0 -0
  297. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/__init__.py +0 -0
  298. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/test_api.py +0 -0
  299. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/tests/test_auth_api.py +0 -0
  300. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/urls.py +0 -0
  301. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user/views.py +0 -0
  302. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/__init__.py +0 -0
  303. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/0001_initial.py +0 -0
  304. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/0002_lowercase_verbose_names.py +0 -0
  305. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/migrations/__init__.py +0 -0
  306. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/models.py +0 -0
  307. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/providers.py +0 -0
  308. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/scope.py +0 -0
  309. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/__init__.py +0 -0
  310. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/ci.py +0 -0
  311. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/common.py +0 -0
  312. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev.py +0 -0
  313. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev_custom_example.py +0 -0
  314. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/settings/dev_default.py +0 -0
  315. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/tests/__init__.py +0 -0
  316. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/tests/test_user_job.py +0 -0
  317. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_custom_user_job/urls.py +0 -0
  318. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/__init__.py +0 -0
  319. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/migrations/0001_initial.py +0 -0
  320. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/migrations/__init__.py +0 -0
  321. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/models.py +0 -0
  322. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/__init__.py +0 -0
  323. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/ci.py +0 -0
  324. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/common.py +0 -0
  325. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev.py +0 -0
  326. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev_custom_example.py +0 -0
  327. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/settings/dev_default.py +0 -0
  328. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/__init__.py +0 -0
  329. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/test_api.py +0 -0
  330. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/tests/test_auth_api.py +0 -0
  331. {django_pfx-1.7.6.dev43 → django_pfx-1.7.6.dev45}/tests_user_email_login/urls.py +0 -0
  332. {django_pfx-1.7.6.dev43 → 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.dev43
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.dev43
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
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.7.5",
3
+ "distance": 45,
4
+ "node": "g8845c1a04b6c6ac983aab0c8fe02537313956a5f",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-28"
8
+ }
@@ -32,6 +32,9 @@ API Reference
32
32
  :undoc-members:
33
33
  :show-inheritance:
34
34
 
35
+ .. autoclass:: pfx.pfxcore.models.UniqueConstraint
36
+ :show-inheritance:
37
+
35
38
  .. autoclass:: pfx.pfxcore.models.AbstractPFXBaseUser
36
39
  :members:
37
40
  :show-inheritance:
@@ -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
@@ -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-05 17:02+0200\n"
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:14
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 NON_FIELD_ERRORS, ValidationError
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
- def __init__(self, *args, message=None, **kwargs):
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 validate_unique to allow to customize error message
89
- for :class:`UniqueConstraint`.
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 = e.update_error_dict({})
103
- non_field_errors = []
104
- for error in errors.get(NON_FIELD_ERRORS, []):
105
- if isinstance(error, ValidationError):
106
- if error.code in ('unique', 'unique_together'):
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
- non_field_errors.append(ValidationError(
146
+ error = ValidationError(
118
147
  message=unique.message,
119
148
  code=error.code,
120
- params=params))
121
- continue
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
 
@@ -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-07-30 09:12+0200\n"
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:57
21
+ #: models.py:58
22
22
  msgid "First Name"
23
23
  msgstr "Prénom"
24
24
 
25
- #: models.py:58
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}"
@@ -1055,6 +1055,34 @@ class BasicAPITest(TestAssertMixin, TestCase):
1055
1055
  response, '__all__.@0',
1056
1056
  'The Hobbit already exists for John Ronald Reuel Tolkien')
1057
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
+
1058
1086
  def test_create_invalid_date(self):
1059
1087
  response = self.client.post(
1060
1088
  '/api/books', dict(
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "1.7.5",
3
- "distance": 43,
4
- "node": "g06cda0545eb88c42c2152cffc096975b4f14e7e3",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-10-27"
8
- }