django-pfx 1.7.dev6__tar.gz → 1.7.2.dev2__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 (199) hide show
  1. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/.gitlab-ci.yml +2 -2
  2. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/PKG-INFO +1 -1
  3. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/django_pfx.egg-info/PKG-INFO +1 -1
  4. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/django_pfx.egg-info/SOURCES.txt +1 -0
  5. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +7 -7
  6. django_pfx-1.7.2.dev2/pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py +24 -0
  7. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/login_ban.py +19 -14
  8. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/rest_views.py +7 -3
  9. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_one2many.py +6 -6
  10. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/.gitignore +0 -0
  11. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/.pre-commit-config.yaml +0 -0
  12. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/LICENSE +0 -0
  13. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/MANIFEST.in +0 -0
  14. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/README.md +0 -0
  15. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/django_pfx.egg-info/dependency_links.txt +0 -0
  16. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/django_pfx.egg-info/requires.txt +0 -0
  17. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/django_pfx.egg-info/top_level.txt +0 -0
  18. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/Makefile +0 -0
  19. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/conf.py +0 -0
  20. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/index.rst +0 -0
  21. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/api.views.rst +0 -0
  22. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/authentication.md +0 -0
  23. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/decorator.md +0 -0
  24. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/generate_openapi.md +0 -0
  25. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/getting_started.md +0 -0
  26. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/internationalisation.md +0 -0
  27. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/model.md +0 -0
  28. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/pfx_views.md +0 -0
  29. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/profiling.md +0 -0
  30. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/settings.md +0 -0
  31. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/doc/source/testing.md +0 -0
  32. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/img/pfx.png +0 -0
  33. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/img/pfx.svg +0 -0
  34. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/make_messages +0 -0
  35. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/manage.py +0 -0
  36. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/__init__.py +0 -0
  37. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/__init__.py +0 -0
  38. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/apidoc/__init__.py +0 -0
  39. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/apidoc/parameters.py +0 -0
  40. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/apidoc/schema.py +0 -0
  41. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/apidoc/tags.py +0 -0
  42. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/apps.py +0 -0
  43. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/decorator/__init__.py +0 -0
  44. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/decorator/rest.py +0 -0
  45. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/default_settings.py +0 -0
  46. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/exceptions.py +0 -0
  47. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/fields/__init__.py +0 -0
  48. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/fields/decimal_field.py +0 -0
  49. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/fields/media_field.py +0 -0
  50. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
  51. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/fields/rich_text_field.py +0 -0
  52. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/http/__init__.py +0 -0
  53. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/http/json_response.py +0 -0
  54. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  55. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/management/__init__.py +0 -0
  56. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/management/commands/__init__.py +0 -0
  57. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  58. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/management/commands/profile.py +0 -0
  59. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/middleware/__init__.py +0 -0
  60. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/middleware/authentication.py +0 -0
  61. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/middleware/locale.py +0 -0
  62. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/middleware/profiling.py +0 -0
  63. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/0001_initial.py +0 -0
  64. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
  65. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
  66. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/__init__.py +0 -0
  67. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
  68. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
  69. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/__init__.py +0 -0
  70. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
  71. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/cache_mixins.py +0 -0
  72. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/not_null_fields.py +0 -0
  73. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/ordered_model_mixin.py +0 -0
  74. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/otp_user_mixin.py +0 -0
  75. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/pfx_models.py +0 -0
  76. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/pfx_user.py +0 -0
  77. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  78. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/serializers/__init__.py +0 -0
  79. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/serializers/json.py +0 -0
  80. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/settings.py +0 -0
  81. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/shortcuts.py +0 -0
  82. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/storage/__init__.py +0 -0
  83. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/storage/exceptions.py +0 -0
  84. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/storage/local_storage.py +0 -0
  85. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/storage/s3_storage.py +0 -0
  86. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
  87. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
  88. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  89. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  90. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  91. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  92. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/test.py +0 -0
  93. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/urls.py +0 -0
  94. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/__init__.py +0 -0
  95. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/authentication_views.py +0 -0
  96. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/fields.py +0 -0
  97. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/filters_views.py +0 -0
  98. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/locale_views.py +0 -0
  99. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
  100. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
  101. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  102. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  103. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/groups.py +0 -0
  104. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  105. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  106. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  107. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  108. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  109. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  110. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  111. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  112. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  113. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset.py +0 -0
  114. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  115. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  116. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  117. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  118. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  119. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/settings/__init__.py +0 -0
  120. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pfx/settings/dev.py +0 -0
  121. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/pyproject.toml +0 -0
  122. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/requirements.txt +0 -0
  123. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/serve-doc +0 -0
  124. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/setup.cfg +0 -0
  125. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/setup.py +0 -0
  126. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/__init__.py +0 -0
  127. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/apps.py +0 -0
  128. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
  129. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/migrations/0001_initial.py +0 -0
  130. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/migrations/0002_alter_book_cover.py +0 -0
  131. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/migrations/0003_book_local_file.py +0 -0
  132. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/migrations/__init__.py +0 -0
  133. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/models.py +0 -0
  134. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/__init__.py +0 -0
  135. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/ci.py +0 -0
  136. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/common.py +0 -0
  137. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/dev.py +0 -0
  138. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/dev_custom_example.py +0 -0
  139. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/settings/dev_default.py +0 -0
  140. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/__init__.py +0 -0
  141. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/basic_api_errors.py +0 -0
  142. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/basic_api_test.py +0 -0
  143. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_api_doc.py +0 -0
  144. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_api_doc_search.py +0 -0
  145. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_auth_api.py +0 -0
  146. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_body_mixin.py +0 -0
  147. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_cache.py +0 -0
  148. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_client.py +0 -0
  149. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_choices.py +0 -0
  150. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_date.py +0 -0
  151. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_decimal.py +0 -0
  152. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_minutes_duration.py +0 -0
  153. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_fields_rich_text.py +0 -0
  154. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_filters.py +0 -0
  155. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_locale_api.py +0 -0
  156. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
  157. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_perm_tests.py +0 -0
  158. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_permissions.py +0 -0
  159. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_perms_api.py +0 -0
  160. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_post_migrate_groups_update.py +0 -0
  161. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_profiling_middleware.py +0 -0
  162. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_settings.py +0 -0
  163. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_shortcuts.py +0 -0
  164. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_timezone_middleware.py +0 -0
  165. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_tools.py +0 -0
  166. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_user_queryset.py +0 -0
  167. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_view_decorators.py +0 -0
  168. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/tests/test_view_fields.py +0 -0
  169. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/urls.py +0 -0
  170. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests/views.py +0 -0
  171. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/__init__.py +0 -0
  172. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/migrations/0001_initial.py +0 -0
  173. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/migrations/__init__.py +0 -0
  174. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/__init__.py +0 -0
  175. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/ci.py +0 -0
  176. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/common.py +0 -0
  177. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/dev.py +0 -0
  178. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/dev_custom_example.py +0 -0
  179. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/settings/dev_default.py +0 -0
  180. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/tests/__init__.py +0 -0
  181. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/tests/test_api.py +0 -0
  182. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/tests/test_auth_api.py +0 -0
  183. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/urls.py +0 -0
  184. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_base_user/views.py +0 -0
  185. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/__init__.py +0 -0
  186. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/migrations/0001_initial.py +0 -0
  187. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/migrations/__init__.py +0 -0
  188. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/models.py +0 -0
  189. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/__init__.py +0 -0
  190. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/ci.py +0 -0
  191. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/common.py +0 -0
  192. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/dev.py +0 -0
  193. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/dev_custom_example.py +0 -0
  194. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/settings/dev_default.py +0 -0
  195. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/tests/__init__.py +0 -0
  196. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/tests/test_api.py +0 -0
  197. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/tests/test_auth_api.py +0 -0
  198. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/urls.py +0 -0
  199. {django_pfx-1.7.dev6 → django_pfx-1.7.2.dev2}/tests_custom_user/views.py +0 -0
@@ -27,7 +27,7 @@ stages:
27
27
 
28
28
  quality check:
29
29
  variables:
30
- DJANGO_VERSION: 'django==4.2.*' # LTS
30
+ DJANGO_VERSION: 'django==5.2.*' # LTS
31
31
  script:
32
32
  - apt-get update
33
33
  - apt-get install -y gettext
@@ -110,7 +110,7 @@ package:
110
110
  - job: quality check
111
111
  - job: test
112
112
  rules:
113
- - if: $CI_COMMIT_TAG =~ /^\d+\.\d+$/
113
+ - if: $CI_COMMIT_TAG =~ /^\d+\.\d+(\.\d+)?$/
114
114
  when: on_success
115
115
  - if: $CI_COMMIT_BRANCH == "master"
116
116
  when: on_success
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-pfx
3
- Version: 1.7.dev6
3
+ Version: 1.7.2.dev2
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.dev6
3
+ Version: 1.7.2.dev2
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
@@ -67,6 +67,7 @@ pfx/pfxcore/middleware/profiling.py
67
67
  pfx/pfxcore/migrations/0001_initial.py
68
68
  pfx/pfxcore/migrations/0002_pfxpermissionsuser.py
69
69
  pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py
70
+ pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py
70
71
  pfx/pfxcore/migrations/__init__.py
71
72
  pfx/pfxcore/migrations/operations/__init__.py
72
73
  pfx/pfxcore/migrations/operations/permissions.py
@@ -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-03-10 15:48+0100\n"
10
+ "POT-Creation-Date: 2026-03-12 12:43+0100\n"
11
11
  "PO-Revision-Date: 2021-06-22 23:31+0200\n"
12
12
  "Last-Translator: \n"
13
13
  "Language-Team: \n"
@@ -67,23 +67,23 @@ msgstr ""
67
67
  msgid "users"
68
68
  msgstr ""
69
69
 
70
- #: models/login_ban.py:45
70
+ #: models/login_ban.py:54
71
71
  msgid "Username"
72
72
  msgstr "Nom d’utilisateur"
73
73
 
74
- #: models/login_ban.py:46
74
+ #: models/login_ban.py:55
75
75
  msgid "Failed counter"
76
76
  msgstr "Compteur d’échec"
77
77
 
78
- #: models/login_ban.py:47
78
+ #: models/login_ban.py:56
79
79
  msgid "Last failed"
80
80
  msgstr "Dernier échec"
81
81
 
82
- #: models/login_ban.py:52
82
+ #: models/login_ban.py:61
83
83
  msgid "Login ban"
84
84
  msgstr "Login banni"
85
85
 
86
- #: models/login_ban.py:53
86
+ #: models/login_ban.py:62
87
87
  msgid "Login bans"
88
88
  msgstr "Login bannis"
89
89
 
@@ -302,7 +302,7 @@ msgstr "{model} {obj} créé."
302
302
  msgid "{model} {obj} updated."
303
303
  msgstr "{model} {obj} modifié."
304
304
 
305
- #: views/rest_views.py:1282
305
+ #: views/rest_views.py:1286
306
306
  #, python-brace-format
307
307
  msgid "{model} {obj} deleted."
308
308
  msgstr "{model} {obj} supprimé."
@@ -0,0 +1,24 @@
1
+ # Generated by Django 4.2.25 on 2026-03-11 09:19
2
+ # flake8: noqa
3
+
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('pfxcore', '0003_delete_pfxpermissionsuser'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name='loginban',
16
+ name='failed_counter',
17
+ field=models.IntegerField(default=0, verbose_name='Failed counter'),
18
+ ),
19
+ migrations.AlterField(
20
+ model_name='loginban',
21
+ name='last_failed',
22
+ field=models.DateTimeField(verbose_name='Last failed'),
23
+ ),
24
+ ]
@@ -1,7 +1,8 @@
1
1
  from datetime import timedelta
2
2
 
3
- from django.db import models
4
- from django.utils import timezone
3
+ from django.db import IntegrityError, models
4
+ from django.db.models import F
5
+ from django.utils import timezone as tz
5
6
  from django.utils.translation import gettext_lazy as _
6
7
 
7
8
  from pfx.pfxcore.settings import settings
@@ -21,19 +22,27 @@ class LoginBanQuerySet(models.QuerySet):
21
22
  ban.failed_counter //
22
23
  settings.PFX_LOGIN_BAN_FAILED_NUMBER - 1))
23
24
  ban_time = ban.last_failed + timedelta(seconds=seconds)
24
- now = timezone.now()
25
+ now = tz.now()
25
26
  if now < ban_time:
26
27
  return ban_time - now
27
28
  return False
28
29
 
30
+ def _increment(self, username, last_failed):
31
+ return self.filter(username=username).update(
32
+ failed_counter=F("failed_counter") + 1,
33
+ last_failed=last_failed)
34
+
29
35
  def ban(self, username):
30
36
  if not username:
31
37
  return
32
- try:
33
- ban = self.get(username=username)
34
- ban.save()
35
- except LoginBan.DoesNotExist:
36
- LoginBan.objects.create(username=username)
38
+ now = tz.now()
39
+ updated = self._increment(username, now)
40
+ if not updated:
41
+ try:
42
+ self.create(
43
+ username=username, failed_counter=1, last_failed=now)
44
+ except IntegrityError:
45
+ self._increment(username, now)
37
46
 
38
47
  def unban(self, username):
39
48
  if not username:
@@ -43,8 +52,8 @@ class LoginBanQuerySet(models.QuerySet):
43
52
 
44
53
  class LoginBan(models.Model):
45
54
  username = models.CharField(_("Username"), max_length=150, unique=True)
46
- failed_counter = models.IntegerField(_("Failed counter"))
47
- last_failed = models.DateTimeField(_("Last failed"), auto_now=True)
55
+ failed_counter = models.IntegerField(_("Failed counter"), default=0)
56
+ last_failed = models.DateTimeField(_("Last failed"))
48
57
 
49
58
  objects = LoginBanQuerySet.as_manager()
50
59
 
@@ -54,7 +63,3 @@ class LoginBan(models.Model):
54
63
 
55
64
  def __str__(self):
56
65
  return self.username
57
-
58
- def save(self, *args, **kwargs):
59
- self.failed_counter = (self.failed_counter or 0) + 1
60
- return super().save(*args, **kwargs)
@@ -570,10 +570,14 @@ class ModelBodyMixin(BodyMixin, ModelMixin):
570
570
  # Force a copy if the existing related
571
571
  # object is linked to another parent.
572
572
  rel_obj.pk = None
573
- for rk, rf in field.related_fields.items():
573
+ for rk, rb in rv.items():
574
+ if rk not in field.related_fields:
575
+ continue
576
+ rf = field.related_fields[rk]
574
577
  rmk, rmv = rf.to_model_value(
575
- rv.get(rk), self.get_related_queryset)
576
- setattr(rel_obj, rmk, rmv)
578
+ rb, self.get_related_queryset)
579
+ if can_write(rmk, field.related_fields):
580
+ setattr(rel_obj, rmk, rmv)
577
581
  setattr(rel_obj, '_save_related', fk_name)
578
582
  res_rel[mk] = mv
579
583
  else:
@@ -40,7 +40,7 @@ class TestOne2ManyModel(JSONReprMixin, models.Model):
40
40
 
41
41
  class TestOne2ManyRelModel(JSONReprMixin, models.Model):
42
42
  name = models.CharField(max_length=30)
43
- descr = models.TextField()
43
+ descr = models.TextField(default="Default description")
44
44
  rel = models.ForeignKey(
45
45
  TestOne2ManyModel, related_name='rels', on_delete=models.CASCADE)
46
46
 
@@ -115,9 +115,9 @@ class TestFieldsOne2Many(TestAssertMixin, TestCase):
115
115
  self.assertRC(response, 200)
116
116
  self.assertSize(response, 'rels', 2)
117
117
  self.assertJE(response, 'rels.@0.name', "R1")
118
- self.assertJE(response, 'rels.@0.descr', "D1")
118
+ self.assertJE(response, 'rels.@0.descr', "Default description")
119
119
  self.assertJE(response, 'rels.@1.name', "R2")
120
- self.assertJE(response, 'rels.@1.descr', "D2")
120
+ self.assertJE(response, 'rels.@1.descr', "Default description")
121
121
 
122
122
  def test_post_field_errors(self):
123
123
  response = self.client.post('/api/test', dict(
@@ -128,7 +128,7 @@ class TestFieldsOne2Many(TestAssertMixin, TestCase):
128
128
  set(response.json().keys()), {'name', 'rels::1::name'})
129
129
  self.assertJE(response, 'name', ["This field cannot be blank."])
130
130
  self.assertJE(
131
- response, 'rels::1::name', ["This field cannot be null."])
131
+ response, 'rels::1::name', ["This field cannot be blank."])
132
132
 
133
133
  response = self.client.post('/api/test', dict(
134
134
  rels=[dict(descr="D1")]
@@ -139,7 +139,7 @@ class TestFieldsOne2Many(TestAssertMixin, TestCase):
139
139
  self.assertJE(response, '__all__', ["You have to set minimum 2 rels."])
140
140
  self.assertJE(response, 'name', ["This field cannot be blank."])
141
141
  self.assertJE(
142
- response, 'rels::0::name', ["This field cannot be null."])
142
+ response, 'rels::0::name', ["This field cannot be blank."])
143
143
 
144
144
  def test_put(self):
145
145
  o = TestOne2ManyModel.objects.create(name="Test")
@@ -156,7 +156,7 @@ class TestFieldsOne2Many(TestAssertMixin, TestCase):
156
156
  self.assertJE(response, 'rels.@0.name', "R1 updated")
157
157
  self.assertJE(response, 'rels.@0.descr', "D1")
158
158
  self.assertJE(response, 'rels.@1.name', "R2")
159
- self.assertJE(response, 'rels.@1.descr', "D2")
159
+ self.assertJE(response, 'rels.@1.descr', "Default description")
160
160
 
161
161
  def test_put_field_errors(self):
162
162
  o = TestOne2ManyModel.objects.create(name="Test")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes