django-pfx 1.4.dev150__tar.gz → 1.4.dev154__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.4.dev150 → django_pfx-1.4.dev154}/PKG-INFO +1 -1
  2. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/django_pfx.egg-info/PKG-INFO +1 -1
  3. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/django_pfx.egg-info/SOURCES.txt +2 -2
  4. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/decorator/rest.py +2 -1
  5. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/fields/__init__.py +1 -1
  6. django_pfx-1.4.dev154/pfx/pfxcore/fields/rich_text_field.py +46 -0
  7. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/fields.py +12 -3
  8. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/common.py +18 -0
  9. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/__init__.py +1 -1
  10. django_pfx-1.4.dev150/tests/tests/test_fields_nh3.py → django_pfx-1.4.dev154/tests/tests/test_fields_rich_text.py +7 -9
  11. django_pfx-1.4.dev150/pfx/pfxcore/fields/nh3_field.py +0 -83
  12. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/.gitignore +0 -0
  13. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/.gitlab-ci.yml +0 -0
  14. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/.pre-commit-config.yaml +0 -0
  15. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/LICENSE +0 -0
  16. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/MANIFEST.in +0 -0
  17. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/README.md +0 -0
  18. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/django_pfx.egg-info/dependency_links.txt +0 -0
  19. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/django_pfx.egg-info/requires.txt +0 -0
  20. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/django_pfx.egg-info/top_level.txt +0 -0
  21. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/Makefile +0 -0
  22. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/conf.py +0 -0
  23. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/index.rst +0 -0
  24. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/api.views.rst +0 -0
  25. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/authentication.md +0 -0
  26. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/decorator.md +0 -0
  27. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/generate_openapi.md +0 -0
  28. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/getting_started.md +0 -0
  29. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/internationalisation.md +0 -0
  30. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/model.md +0 -0
  31. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/pfx_views.md +0 -0
  32. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/profiling.md +0 -0
  33. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/settings.md +0 -0
  34. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/doc/source/testing.md +0 -0
  35. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/img/pfx.png +0 -0
  36. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/img/pfx.svg +0 -0
  37. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/make_messages +0 -0
  38. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/manage.py +0 -0
  39. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/__init__.py +0 -0
  40. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/__init__.py +0 -0
  41. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/apidoc/__init__.py +0 -0
  42. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/apidoc/parameters.py +0 -0
  43. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/apidoc/schema.py +0 -0
  44. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/apidoc/tags.py +0 -0
  45. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/apps.py +0 -0
  46. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/decorator/__init__.py +0 -0
  47. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/default_settings.py +0 -0
  48. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/exceptions.py +0 -0
  49. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/fields/decimal_field.py +0 -0
  50. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/fields/media_field.py +0 -0
  51. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
  52. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/http/__init__.py +0 -0
  53. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/http/json_response.py +0 -0
  54. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  55. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
  56. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/management/__init__.py +0 -0
  57. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/management/commands/__init__.py +0 -0
  58. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  59. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/management/commands/profile.py +0 -0
  60. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/middleware/__init__.py +0 -0
  61. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/middleware/authentication.py +0 -0
  62. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/middleware/locale.py +0 -0
  63. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/middleware/profiling.py +0 -0
  64. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/0001_initial.py +0 -0
  65. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
  66. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
  67. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/__init__.py +0 -0
  68. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
  69. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
  70. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/__init__.py +0 -0
  71. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
  72. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/cache_mixins.py +0 -0
  73. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/login_ban.py +0 -0
  74. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/not_null_fields.py +0 -0
  75. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/ordered_model_mixin.py +0 -0
  76. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/otp_user_mixin.py +0 -0
  77. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/pfx_models.py +0 -0
  78. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/pfx_user.py +0 -0
  79. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  80. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/serializers/__init__.py +0 -0
  81. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/serializers/json.py +0 -0
  82. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/settings.py +0 -0
  83. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/shortcuts.py +0 -0
  84. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/storage/__init__.py +0 -0
  85. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/storage/exceptions.py +0 -0
  86. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/storage/local_storage.py +0 -0
  87. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/storage/s3_storage.py +0 -0
  88. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
  89. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
  90. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  91. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  92. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  93. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  94. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/test.py +0 -0
  95. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/urls.py +0 -0
  96. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/__init__.py +0 -0
  97. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/authentication_views.py +0 -0
  98. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/filters_views.py +0 -0
  99. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/locale_views.py +0 -0
  100. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
  101. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
  102. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  103. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  104. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/groups.py +0 -0
  105. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  106. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  107. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  108. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  109. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  110. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  111. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  112. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  113. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  114. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset.py +0 -0
  115. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  116. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  117. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  118. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  119. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  120. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/pfxcore/views/rest_views.py +0 -0
  121. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/settings/__init__.py +0 -0
  122. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pfx/settings/dev.py +0 -0
  123. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/pyproject.toml +0 -0
  124. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/requirements.txt +0 -0
  125. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/serve-doc +0 -0
  126. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/setup.cfg +0 -0
  127. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/setup.py +0 -0
  128. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/__init__.py +0 -0
  129. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/apps.py +0 -0
  130. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
  131. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/migrations/0001_initial.py +0 -0
  132. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/migrations/0002_alter_book_cover.py +0 -0
  133. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/migrations/0003_book_local_file.py +0 -0
  134. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/migrations/__init__.py +0 -0
  135. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/models.py +0 -0
  136. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/__init__.py +0 -0
  137. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/ci.py +0 -0
  138. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/dev.py +0 -0
  139. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/dev_custom_example.py +0 -0
  140. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/settings/dev_default.py +0 -0
  141. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/basic_api_errors.py +0 -0
  142. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/basic_api_test.py +0 -0
  143. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_api_doc.py +0 -0
  144. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_api_doc_search.py +0 -0
  145. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_auth_api.py +0 -0
  146. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_body_mixin.py +0 -0
  147. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_cache.py +0 -0
  148. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_client.py +0 -0
  149. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_fields_choices.py +0 -0
  150. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_fields_date.py +0 -0
  151. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_fields_decimal.py +0 -0
  152. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_fields_minutes_duration.py +0 -0
  153. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_fields_one2many.py +0 -0
  154. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_filters.py +0 -0
  155. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_locale_api.py +0 -0
  156. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
  157. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_perm_tests.py +0 -0
  158. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_permissions.py +0 -0
  159. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_perms_api.py +0 -0
  160. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_post_migrate_groups_update.py +0 -0
  161. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_profiling_middleware.py +0 -0
  162. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_settings.py +0 -0
  163. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_shortcuts.py +0 -0
  164. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_timezone_middleware.py +0 -0
  165. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_tools.py +0 -0
  166. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_user_queryset.py +0 -0
  167. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_view_decorators.py +0 -0
  168. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/tests/test_view_fields.py +0 -0
  169. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/urls.py +0 -0
  170. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests/views.py +0 -0
  171. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/__init__.py +0 -0
  172. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/migrations/0001_initial.py +0 -0
  173. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/migrations/__init__.py +0 -0
  174. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/__init__.py +0 -0
  175. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/ci.py +0 -0
  176. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/common.py +0 -0
  177. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/dev.py +0 -0
  178. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/dev_custom_example.py +0 -0
  179. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/settings/dev_default.py +0 -0
  180. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/tests/__init__.py +0 -0
  181. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/tests/test_api.py +0 -0
  182. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/tests/test_auth_api.py +0 -0
  183. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/urls.py +0 -0
  184. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_base_user/views.py +0 -0
  185. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/__init__.py +0 -0
  186. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/migrations/0001_initial.py +0 -0
  187. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/migrations/__init__.py +0 -0
  188. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/models.py +0 -0
  189. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/__init__.py +0 -0
  190. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/ci.py +0 -0
  191. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/common.py +0 -0
  192. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/dev.py +0 -0
  193. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/dev_custom_example.py +0 -0
  194. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/settings/dev_default.py +0 -0
  195. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/tests/__init__.py +0 -0
  196. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/tests/test_api.py +0 -0
  197. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/tests/test_auth_api.py +0 -0
  198. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/urls.py +0 -0
  199. {django_pfx-1.4.dev150 → django_pfx-1.4.dev154}/tests_custom_user/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-pfx
3
- Version: 1.4.dev150
3
+ Version: 1.4.dev154
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.4.dev150
3
+ Version: 1.4.dev154
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
@@ -51,7 +51,7 @@ pfx/pfxcore/fields/__init__.py
51
51
  pfx/pfxcore/fields/decimal_field.py
52
52
  pfx/pfxcore/fields/media_field.py
53
53
  pfx/pfxcore/fields/minutes_duration_field.py
54
- pfx/pfxcore/fields/nh3_field.py
54
+ pfx/pfxcore/fields/rich_text_field.py
55
55
  pfx/pfxcore/http/__init__.py
56
56
  pfx/pfxcore/http/json_response.py
57
57
  pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo
@@ -149,8 +149,8 @@ tests/tests/test_fields_choices.py
149
149
  tests/tests/test_fields_date.py
150
150
  tests/tests/test_fields_decimal.py
151
151
  tests/tests/test_fields_minutes_duration.py
152
- tests/tests/test_fields_nh3.py
153
152
  tests/tests/test_fields_one2many.py
153
+ tests/tests/test_fields_rich_text.py
154
154
  tests/tests/test_filters.py
155
155
  tests/tests/test_locale_api.py
156
156
  tests/tests/test_ordered_rest_view_mixin.py
@@ -54,11 +54,12 @@ def rest_api(
54
54
  return decorator
55
55
 
56
56
 
57
- def rest_property(string=None, type="CharField", field=None):
57
+ def rest_property(string=None, type="CharField", field=None, order=None):
58
58
  def decorator(func):
59
59
  func.short_description = string
60
60
  func.field_type = type
61
61
  func.field = field
62
+ func.order = order
62
63
  return property(func)
63
64
  return decorator
64
65
 
@@ -1,4 +1,4 @@
1
1
  from .decimal_field import DecimalField
2
2
  from .media_field import MediaField
3
3
  from .minutes_duration_field import MinutesDurationField
4
- from .nh3_field import NH3Field
4
+ from .rich_text_field import RichTextField
@@ -0,0 +1,46 @@
1
+ from django.conf import settings
2
+ from django.core.exceptions import ImproperlyConfigured
3
+ from django.db import models
4
+ from django.utils.safestring import mark_safe
5
+
6
+ import nh3
7
+
8
+
9
+ class RichTextField(models.TextField):
10
+ """
11
+ A TextField that automatically sanitizes HTML input using nh3.
12
+
13
+ Args:
14
+ nh3_config (str|None): Key of the NH3_CONFIGS dict from settings.
15
+ Set to None to disable sanitization for this field.
16
+ """
17
+ def __init__(self, *args, nh3_config='default', **kwargs):
18
+ super().__init__(*args, **kwargs)
19
+ if nh3_config is None:
20
+ self.nh3_kwargs = None
21
+ else:
22
+ if (not hasattr(settings, 'NH3_CONFIGS') or
23
+ nh3_config not in settings.NH3_CONFIGS):
24
+ raise ImproperlyConfigured(
25
+ f"Missing NH3_CONFIGS['{nh3_config}'] configuration. "
26
+ "You must use an existing configuration or set "
27
+ "nh3_config=None to explicitly disable sanitization "
28
+ "for this field.")
29
+ self.nh3_kwargs = settings.NH3_CONFIGS[nh3_config]
30
+
31
+ def pre_save(self, model_instance, add):
32
+ data = getattr(model_instance, self.attname)
33
+ if data is None:
34
+ return data
35
+ clean_value = (
36
+ nh3.clean(data, **self.nh3_kwargs)
37
+ if self.nh3_kwargs and data else data or "")
38
+ setattr(model_instance, self.attname, mark_safe(clean_value))
39
+ return clean_value
40
+
41
+ def from_db_value(self, value, expression, connection):
42
+ if value is None:
43
+ return value
44
+ # Values are sanitized before saving, so any value returned from the DB
45
+ # is safe to render unescaped.
46
+ return mark_safe(value)
@@ -29,6 +29,7 @@ class ModelList(list):
29
29
  class FieldType:
30
30
  CharField = "CharField"
31
31
  TextField = "TextField"
32
+ RichTextField = "RichTextField"
32
33
  BooleanField = "BooleanField"
33
34
  IntegerField = "IntegerField"
34
35
  FloatField = "FloatField"
@@ -45,6 +46,7 @@ class FieldType:
45
46
  (pfx_fields.MinutesDurationField, MinutesDurationField),
46
47
  (pfx_fields.MediaField, MediaField),
47
48
  (pfx_fields.DecimalField, DecimalField),
49
+ (pfx_fields.RichTextField, RichTextField),
48
50
  (models.BooleanField, BooleanField),
49
51
  (models.IntegerField, IntegerField),
50
52
  (models.FloatField, FloatField),
@@ -64,6 +66,7 @@ class FieldType:
64
66
  APIDOC_FIELD_BINDING = {
65
67
  CharField: "string",
66
68
  TextField: "string",
69
+ RichTextField: "string",
67
70
  BooleanField: "boolean",
68
71
  IntegerField: "number",
69
72
  FloatField: "number",
@@ -106,7 +109,7 @@ def get_db_type(field):
106
109
  class ViewField:
107
110
  def __init__(
108
111
  self, name, verbose_name=None, alias=None,
109
- field_type=None, db_type=None,
112
+ field_type=None, db_type=None, order=None,
110
113
  readonly=False, readonly_create=False, readonly_update=False,
111
114
  choices=None, json_repr=None, media_field_api=None,
112
115
  related_model=None, related_model_api=None, related_fields=None,
@@ -118,6 +121,7 @@ class ViewField:
118
121
  self.verbose_name = verbose_name or name
119
122
  self.field_type = field_type
120
123
  self.db_type = db_type
124
+ self.order = order
121
125
  self.choices = dict(choices or [])
122
126
  self.json_repr = json_repr
123
127
  self.media_field_api = media_field_api
@@ -150,6 +154,7 @@ class ViewField:
150
154
  res['readonly'] = dict(
151
155
  post=self.readonly_create,
152
156
  put=self.readonly_update)
157
+ res['order'] = self.order
153
158
  return res
154
159
 
155
160
  def get_value(self, obj):
@@ -213,6 +218,7 @@ class ViewField:
213
218
  def from_property(cls, name, prop, **kwargs):
214
219
  kwargs['readonly'] = True
215
220
  if hasattr(prop, 'fget'):
221
+ setifnone(kwargs, 'order', getattr(prop.fget, 'order', None))
216
222
  field = getattr(prop.fget, 'field', None)
217
223
  if field:
218
224
  return cls.from_model_field(name, field, **kwargs)
@@ -237,6 +243,8 @@ class ViewField:
237
243
  kwargs, 'field_type', FieldType.from_model_field(field.__class__))
238
244
  setifnone(
239
245
  kwargs, 'db_type', get_db_type(field))
246
+ if kwargs.get('order') == '__auto__':
247
+ kwargs['order'] = name
240
248
  return ViewModelField(
241
249
  name, model_field=field, **kwargs)
242
250
 
@@ -254,6 +262,7 @@ class ViewField:
254
262
  if isinstance(attr, (property, cached_property)):
255
263
  return cls.from_property(name, attr, **kwargs)
256
264
  field = field or attr_model._meta.get_field(attr_name)
265
+ kwargs['order'] = '__auto__'
257
266
  if LOOKUP_SEP in name:
258
267
  kwargs['readonly'] = True
259
268
  return cls.from_model_field(name, field, **kwargs)
@@ -446,7 +455,7 @@ class VF:
446
455
  choices=None, select_related=None, prefetch_related=None,
447
456
  json_repr=None, related_model=None, related_model_api=None,
448
457
  field=None, related_fields=None, media_field_api=None,
449
- db_type=None):
458
+ db_type=None, order=None):
450
459
  self.kwargs = dict(
451
460
  name=name, verbose_name=verbose_name, field_type=field_type,
452
461
  alias=alias,
@@ -456,7 +465,7 @@ class VF:
456
465
  json_repr=json_repr, related_model=related_model,
457
466
  related_model_api=related_model_api, field=field,
458
467
  related_fields=related_fields, media_field_api=media_field_api,
459
- db_type=db_type)
468
+ db_type=db_type, order=order)
460
469
 
461
470
  def to_field(self, model):
462
471
  return ViewField.from_name(model, **self.kwargs)
@@ -58,6 +58,24 @@ TEMPLATES = [
58
58
  }
59
59
  ]
60
60
 
61
+ NH3_CONFIGS = {
62
+ 'default': {
63
+ 'tags': None,
64
+ 'attributes': None,
65
+ 'strip_comments': True,
66
+ 'url_schemes': None,
67
+ 'attribute_filter': None,
68
+ 'link_rel': None,
69
+ 'generic_attribute_prefixes': None,
70
+ 'tag_attribute_values': {},
71
+ 'set_tag_attribute_values': {},
72
+ },
73
+ 'custom': {
74
+ 'tags': {'h1', 'p', 'span'},
75
+ 'attributes': {'*': {'class'}},
76
+ }
77
+ }
78
+
61
79
  LOGGING = {
62
80
  'version': 1,
63
81
  'disable_existing_logger': False,
@@ -10,8 +10,8 @@ from .test_fields_choices import TestFieldsChoices
10
10
  from .test_fields_date import TestFieldsDate
11
11
  from .test_fields_decimal import TestFieldsDecimal
12
12
  from .test_fields_minutes_duration import TestFieldsMinutesDuration
13
- from .test_fields_nh3 import TestFieldsNh3
14
13
  from .test_fields_one2many import TestFieldsOne2Many
14
+ from .test_fields_rich_text import TestFieldsRichText
15
15
  from .test_filters import FiltersTest
16
16
  from .test_locale_api import LocaleAPITest
17
17
  from .test_ordered_rest_view_mixin import TestOrderedRestViewMixin
@@ -2,16 +2,14 @@ from django.db import connection, models
2
2
  from django.test import TestCase
3
3
  from django.test.utils import override_settings
4
4
 
5
- from pfx.pfxcore.fields import NH3Field
5
+ from pfx.pfxcore.fields import RichTextField
6
6
  from pfx.pfxcore.models import JSONReprMixin
7
7
  from pfx.pfxcore.test import TestAssertMixin
8
8
 
9
9
 
10
- class TestNh3Model(JSONReprMixin, models.Model):
11
- html = NH3Field()
12
- custom_html = NH3Field(
13
- allowed_tags={'h1', 'p', 'span'},
14
- allowed_attributes={'*': {'class'}})
10
+ class TestRichTextFieldModel(JSONReprMixin, models.Model):
11
+ html = RichTextField()
12
+ custom_html = RichTextField(nh3_config='custom')
15
13
 
16
14
  class Meta:
17
15
  verbose_name = "TestModel"
@@ -20,15 +18,15 @@ class TestNh3Model(JSONReprMixin, models.Model):
20
18
 
21
19
 
22
20
  @override_settings(ROOT_URLCONF=__name__)
23
- class TestFieldsNh3(TestAssertMixin, TestCase):
21
+ class TestFieldsRichText(TestAssertMixin, TestCase):
24
22
 
25
23
  @classmethod
26
24
  def setUpTestData(cls):
27
25
  with connection.schema_editor() as schema_editor:
28
- schema_editor.create_model(TestNh3Model)
26
+ schema_editor.create_model(TestRichTextFieldModel)
29
27
 
30
28
  def test_save(self):
31
- t = TestNh3Model.objects.create(
29
+ t = TestRichTextFieldModel.objects.create(
32
30
  html="<unknown>AAA</unknown>",
33
31
  custom_html='<h1>TEST</h1>'
34
32
  '<script>alert("hello")</script>'
@@ -1,83 +0,0 @@
1
- from django.conf import settings
2
- from django.db import models
3
- from django.utils.safestring import mark_safe
4
-
5
- import nh3
6
-
7
-
8
- def get_nh3_default_options():
9
- nh3_args = {}
10
- nh3_settings = {
11
- "NH3_ALLOWED_TAGS": "tags",
12
- "NH3_ALLOWED_ATTRIBUTES": "attributes",
13
- "NH3_STRIP_COMMENTS": "strip_comments",
14
- "NH3_URL_SCHEMES": "url_schemes",
15
- "NH3_ATTRIBUTE_FILTER": "attribute_filter",
16
- "NH3_LINK_REL": "link_rel",
17
- "NH3_GENERIC_ATTRIBUTE_PREFIXES": "generic_attribute_prefixes",
18
- "NH3_TAG_ATTRIBUTE_VALUES": "tag_attribute_values",
19
- "NH3_SET_TAG_ATTRIBUTE_VALUES": "set_tag_attribute_values",
20
- }
21
-
22
- for setting, kwarg in nh3_settings.items():
23
- if hasattr(settings, setting):
24
- attr = getattr(settings, setting)
25
- nh3_args[kwarg] = attr
26
-
27
- return nh3_args
28
-
29
-
30
- class NH3Field(models.TextField):
31
- def __init__(
32
- self,
33
- allowed_tags=None,
34
- allowed_attributes=None,
35
- url_schemes=None,
36
- strip_comments=None,
37
- attribute_filter=None,
38
- link_rel=None,
39
- generic_attribute_prefixes=None,
40
- tag_attribute_values=None,
41
- set_tag_attribute_values=None,
42
- *args,
43
- **kwargs,
44
- ):
45
- super().__init__(*args, **kwargs)
46
-
47
- self.nh3_kwargs = get_nh3_default_options()
48
-
49
- if allowed_tags:
50
- self.nh3_kwargs["tags"] = allowed_tags
51
- if allowed_attributes:
52
- self.nh3_kwargs["attributes"] = allowed_attributes
53
- if url_schemes:
54
- self.nh3_kwargs["url_schemes"] = url_schemes
55
- if strip_comments:
56
- self.nh3_kwargs["strip_comments"] = strip_comments
57
- if attribute_filter:
58
- self.nh3_kwargs["attribute_filter"] = attribute_filter
59
- if link_rel:
60
- self.nh3_kwargs["link_rel"] = link_rel
61
- if generic_attribute_prefixes:
62
- self.nh3_kwargs["generic_attribute_prefixes"] = (
63
- generic_attribute_prefixes)
64
- if tag_attribute_values:
65
- self.nh3_kwargs["tag_attribute_values"] = tag_attribute_values
66
- if set_tag_attribute_values:
67
- self.nh3_kwargs["set_tag_attribute_values"] = (
68
- set_tag_attribute_values)
69
-
70
- def pre_save(self, model_instance, add):
71
- data = getattr(model_instance, self.attname)
72
- if data is None:
73
- return data
74
- clean_value = nh3.clean(data, **self.nh3_kwargs) if data else ""
75
- setattr(model_instance, self.attname, mark_safe(clean_value))
76
- return clean_value
77
-
78
- def from_db_value(self, value, expression, connection):
79
- if value is None:
80
- return value
81
- # Values are sanitised before saving, so any value returned from the DB
82
- # is safe to render unescaped.
83
- return mark_safe(value)
File without changes