django-camomilla-cms 6.0.0b15__tar.gz → 6.0.0b17__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 (147) hide show
  1. {django_camomilla_cms-6.0.0b15/django_camomilla_cms.egg-info → django_camomilla_cms-6.0.0b17}/PKG-INFO +18 -11
  2. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/README.md +6 -2
  3. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/__init__.py +1 -1
  4. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
  5. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/dynamic_pages_urls.py +6 -2
  6. django_camomilla_cms-6.0.0b17/camomilla/managers/pages.py +116 -0
  7. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/model_api.py +14 -7
  8. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/media.py +1 -1
  9. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/menu.py +10 -4
  10. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/page.py +189 -127
  11. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/openapi/schema.py +17 -8
  12. django_camomilla_cms-6.0.0b17/camomilla/redirects.py +10 -0
  13. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/base/__init__.py +6 -4
  14. django_camomilla_cms-6.0.0b17/camomilla/serializers/fields/__init__.py +9 -0
  15. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/fields/related.py +10 -4
  16. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/__init__.py +23 -0
  17. django_camomilla_cms-6.0.0b15/camomilla/serializers/fields/__init__.py → django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/fields.py +3 -4
  18. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/filter_fields.py +57 -0
  19. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/json.py +34 -0
  20. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/language.py +32 -0
  21. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/nesting.py +35 -0
  22. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/optimize.py +91 -0
  23. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/ordering.py +34 -0
  24. django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/page.py +58 -0
  25. django_camomilla_cms-6.0.0b15/camomilla/contrib/rest_framework/serializer.py → django_camomilla_cms-6.0.0b17/camomilla/serializers/mixins/translation.py +16 -56
  26. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/utils.py +5 -3
  27. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/validators.py +6 -2
  28. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/settings.py +10 -2
  29. django_camomilla_cms-6.0.0b17/camomilla/storages/default.py +12 -0
  30. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/storages/optimize.py +2 -2
  31. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/storages/overwrite.py +2 -2
  32. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/parts/menu.html +1 -1
  33. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templatetags/menus.py +3 -0
  34. django_camomilla_cms-6.0.0b17/camomilla/theme/__init__.py +1 -0
  35. django_camomilla_cms-6.0.0b15/camomilla/theme/admin.py → django_camomilla_cms-6.0.0b17/camomilla/theme/admin/__init__.py +22 -20
  36. django_camomilla_cms-6.0.0b17/camomilla/theme/admin/pages.py +46 -0
  37. django_camomilla_cms-6.0.0b17/camomilla/theme/admin/translations.py +13 -0
  38. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/apps.py +1 -5
  39. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/translation.py +7 -1
  40. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/urls.py +2 -5
  41. django_camomilla_cms-6.0.0b17/camomilla/utils/query_parser.py +167 -0
  42. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/translation.py +47 -5
  43. django_camomilla_cms-6.0.0b17/camomilla/views/base/__init__.py +38 -0
  44. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/medias.py +1 -1
  45. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/menus.py +0 -2
  46. django_camomilla_cms-6.0.0b17/camomilla/views/mixins/__init__.py +17 -0
  47. django_camomilla_cms-6.0.0b17/camomilla/views/mixins/bulk_actions.py +22 -0
  48. django_camomilla_cms-6.0.0b17/camomilla/views/mixins/language.py +33 -0
  49. django_camomilla_cms-6.0.0b17/camomilla/views/mixins/optimize.py +18 -0
  50. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/mixins/pagination.py +12 -18
  51. django_camomilla_cms-6.0.0b17/camomilla/views/mixins/permissions.py +6 -0
  52. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/pages.py +12 -2
  53. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17/django_camomilla_cms.egg-info}/PKG-INFO +18 -11
  54. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/django_camomilla_cms.egg-info/SOURCES.txt +32 -5
  55. django_camomilla_cms-6.0.0b17/django_camomilla_cms.egg-info/requires.txt +11 -0
  56. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/pyproject.toml +9 -7
  57. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/setup.py +1 -1
  58. django_camomilla_cms-6.0.0b17/tests/fixtures/__init__.py +17 -0
  59. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/tests/test_api.py +2 -11
  60. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/tests/test_camomilla_filters.py +7 -13
  61. django_camomilla_cms-6.0.0b17/tests/test_media.py +113 -0
  62. django_camomilla_cms-6.0.0b17/tests/test_menu.py +97 -0
  63. django_camomilla_cms-6.0.0b17/tests/test_model_api.py +68 -0
  64. django_camomilla_cms-6.0.0b17/tests/test_model_api_permissions.py +39 -0
  65. django_camomilla_cms-6.0.0b17/tests/test_model_api_register.py +393 -0
  66. django_camomilla_cms-6.0.0b17/tests/test_pages.py +343 -0
  67. django_camomilla_cms-6.0.0b17/tests/test_query_parser.py +58 -0
  68. django_camomilla_cms-6.0.0b17/tests/test_templates_context.py +111 -0
  69. django_camomilla_cms-6.0.0b17/tests/test_utils.py +86 -0
  70. django_camomilla_cms-6.0.0b17/tests/utils/api.py +28 -0
  71. django_camomilla_cms-6.0.0b17/tests/utils/media.py +9 -0
  72. django_camomilla_cms-6.0.0b15/camomilla/managers/pages.py +0 -31
  73. django_camomilla_cms-6.0.0b15/camomilla/serializers/fields/json.py +0 -49
  74. django_camomilla_cms-6.0.0b15/camomilla/serializers/mixins/__init__.py +0 -195
  75. django_camomilla_cms-6.0.0b15/camomilla/theme/__init__.py +0 -1
  76. django_camomilla_cms-6.0.0b15/camomilla/views/base/__init__.py +0 -8
  77. django_camomilla_cms-6.0.0b15/camomilla/views/mixins/__init__.py +0 -69
  78. django_camomilla_cms-6.0.0b15/django_camomilla_cms.egg-info/requires.txt +0 -9
  79. django_camomilla_cms-6.0.0b15/tests/test_utils.py +0 -86
  80. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/LICENSE +0 -0
  81. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/MANIFEST.in +0 -0
  82. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/apps.py +0 -0
  83. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/authentication.py +0 -0
  84. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/context_processors.py +0 -0
  85. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/contrib/__init__.py +0 -0
  86. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/contrib/modeltranslation/__init__.py +0 -0
  87. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/defaults.py +0 -0
  88. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/exceptions.py +0 -0
  89. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/fields/__init__.py +0 -0
  90. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/fields/json.py +0 -0
  91. {django_camomilla_cms-6.0.0b15/camomilla/contrib/rest_framework → django_camomilla_cms-6.0.0b17/camomilla/management}/__init__.py +0 -0
  92. {django_camomilla_cms-6.0.0b15/camomilla/management → django_camomilla_cms-6.0.0b17/camomilla/management/commands}/__init__.py +0 -0
  93. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/management/commands/regenerate_thumbnails.py +0 -0
  94. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/managers/__init__.py +0 -0
  95. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/__init__.py +0 -0
  96. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/article.py +0 -0
  97. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/content.py +0 -0
  98. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/models/mixins/__init__.py +0 -0
  99. {django_camomilla_cms-6.0.0b15/camomilla/management/commands → django_camomilla_cms-6.0.0b17/camomilla/openapi}/__init__.py +0 -0
  100. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/parsers.py +0 -0
  101. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/permissions.py +0 -0
  102. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/__init__.py +0 -0
  103. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/article.py +0 -0
  104. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/content_type.py +0 -0
  105. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/fields/file.py +0 -0
  106. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/media.py +0 -0
  107. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/menu.py +0 -0
  108. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/page.py +0 -0
  109. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/serializers/user.py +0 -0
  110. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/sitemap.py +0 -0
  111. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/storages/__init__.py +0 -0
  112. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/admin/camomilla/page/change_form.html +0 -0
  113. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/articles/default.html +0 -0
  114. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/base.html +0 -0
  115. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/pages/default.html +0 -0
  116. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/parts/langswitch.html +0 -0
  117. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates/defaults/widgets/media_select_multiple.html +0 -0
  118. {django_camomilla_cms-6.0.0b15/camomilla/openapi → django_camomilla_cms-6.0.0b17/camomilla/templates_context}/__init__.py +0 -0
  119. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates_context/autodiscover.py +0 -0
  120. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templates_context/rendering.py +0 -0
  121. {django_camomilla_cms-6.0.0b15/camomilla/templates_context → django_camomilla_cms-6.0.0b17/camomilla/templatetags}/__init__.py +0 -0
  122. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/templatetags/camomilla_filters.py +0 -0
  123. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/static/admin/css/responsive.css +0 -0
  124. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/static/admin/img/favicon.ico +0 -0
  125. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/static/admin/img/logo.svg +0 -0
  126. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/templates/admin/base.html +0 -0
  127. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/theme/templates/rosetta/base.html +0 -0
  128. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/__init__.py +0 -0
  129. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/getters.py +0 -0
  130. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/normalization.py +0 -0
  131. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/seo.py +0 -0
  132. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/setters.py +0 -0
  133. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/utils/templates.py +0 -0
  134. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/__init__.py +0 -0
  135. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/articles.py +0 -0
  136. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/contents.py +0 -0
  137. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/decorators.py +0 -0
  138. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/languages.py +0 -0
  139. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/mixins/ordering.py +0 -0
  140. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/tags.py +0 -0
  141. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/camomilla/views/users.py +0 -0
  142. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/django_camomilla_cms.egg-info/dependency_links.txt +0 -0
  143. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/django_camomilla_cms.egg-info/top_level.txt +0 -0
  144. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/setup.cfg +0 -0
  145. {django_camomilla_cms-6.0.0b15/camomilla/templatetags → django_camomilla_cms-6.0.0b17/tests}/__init__.py +0 -0
  146. {django_camomilla_cms-6.0.0b15 → django_camomilla_cms-6.0.0b17}/tests/test_models.py +0 -0
  147. {django_camomilla_cms-6.0.0b15/tests → django_camomilla_cms-6.0.0b17/tests/utils}/__init__.py +0 -0
@@ -1,30 +1,33 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: django-camomilla-cms
3
- Version: 6.0.0b15
3
+ Version: 6.0.0b17
4
4
  Summary: Django powered cms
5
5
  Author-email: Lotrèk <dimmitutto@lotrek.it>
6
6
  License: MIT
7
- Project-URL: Homepage, https://github.com/lotrekagency/camomilla
7
+ Project-URL: Homepage, https://github.com/camomillacms/camomilla-core
8
8
  Keywords: cms,django,api cms
9
9
  Classifier: Environment :: Web Environment
10
10
  Classifier: Framework :: Django
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Programming Language :: Python
13
13
  Classifier: Programming Language :: Python :: 3
14
- Requires-Python: >=3.6
14
+ Requires-Python: <=3.13,>=3.8
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: django-modeltranslation~=0.18.11
17
+ Requires-Dist: django-modeltranslation<=0.18.12,>=0.18.7
18
18
  Requires-Dist: djsuperadmin<1.0.0,>=0.9
19
- Requires-Dist: djangorestframework<4.0.0,>=3.10.0
19
+ Requires-Dist: djangorestframework<=3.14.0,>=3.10.0
20
+ Requires-Dist: django-structured-json-field>=0.4.1
21
+ Requires-Dist: Pillow>=10.0.0
20
22
  Requires-Dist: django-admin-interface<1.0.0,>=0.26.0
21
- Requires-Dist: Pillow<10.0.0,>=6.2.0
22
23
  Requires-Dist: django-ckeditor<7.0.0,>=5.7.1
23
- Requires-Dist: django-structured-json-field==0.2.0
24
+ Requires-Dist: django-tinymce<5.0.0,>=4.1.0
24
25
  Requires-Dist: python-magic<0.5,>=0.4
25
- Requires-Dist: Django>=3.2
26
+ Requires-Dist: Django<6,>=3.2
27
+ Requires-Dist: django_jsonform>=2.23
28
+ Dynamic: license-file
26
29
 
27
- # camomilla django cms [![PyPI](https://img.shields.io/pypi/v/django-camomilla-cms?style=flat-square)](https://pypi.org/project/django-camomilla-cms) ![Codecov](https://img.shields.io/codecov/c/github/lotrekagency/camomilla?style=flat-square) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/lotrekagency/camomilla/Test,%20Coverage%20and%20Release?style=flat-square) [![GitHub](https://img.shields.io/github/license/lotrekagency/camomilla?style=flat-square)](./LICENSE)
30
+ # camomilla django cms [![PyPI](https://img.shields.io/pypi/v/django-camomilla-cms?style=flat-square)](https://pypi.org/project/django-camomilla-cms) ![Codecov](https://img.shields.io/codecov/c/github/camomillacms/camomilla-core?style=flat-square) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/camomillacms/camomilla-core/Test,%20Coverage%20and%20Release?style=flat-square) [![GitHub](https://img.shields.io/github/license/camomillacms/camomilla-core?style=flat-square)](./LICENSE)
28
31
 
29
32
  ## Install
30
33
 
@@ -35,7 +38,7 @@ $ pip install django-camomilla-cms
35
38
  ## Setup
36
39
  ```shell
37
40
  $ mkdir -p camomilla_migrations
38
- $ touch camomilla_migrations.__init__.py
41
+ $ touch camomilla_migrations/__init__.py
39
42
  $ python manage.py makemigrations camomilla
40
43
  $ python manage.py migrate camomilla
41
44
  ```
@@ -70,3 +73,7 @@ INSTALLED_APPS = [
70
73
 
71
74
  pip install -r requirements-dev.txt
72
75
  make test
76
+
77
+ ## Run format with black
78
+
79
+ black camomilla
@@ -1,4 +1,4 @@
1
- # camomilla django cms [![PyPI](https://img.shields.io/pypi/v/django-camomilla-cms?style=flat-square)](https://pypi.org/project/django-camomilla-cms) ![Codecov](https://img.shields.io/codecov/c/github/lotrekagency/camomilla?style=flat-square) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/lotrekagency/camomilla/Test,%20Coverage%20and%20Release?style=flat-square) [![GitHub](https://img.shields.io/github/license/lotrekagency/camomilla?style=flat-square)](./LICENSE)
1
+ # camomilla django cms [![PyPI](https://img.shields.io/pypi/v/django-camomilla-cms?style=flat-square)](https://pypi.org/project/django-camomilla-cms) ![Codecov](https://img.shields.io/codecov/c/github/camomillacms/camomilla-core?style=flat-square) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/camomillacms/camomilla-core/Test,%20Coverage%20and%20Release?style=flat-square) [![GitHub](https://img.shields.io/github/license/camomillacms/camomilla-core?style=flat-square)](./LICENSE)
2
2
 
3
3
  ## Install
4
4
 
@@ -9,7 +9,7 @@ $ pip install django-camomilla-cms
9
9
  ## Setup
10
10
  ```shell
11
11
  $ mkdir -p camomilla_migrations
12
- $ touch camomilla_migrations.__init__.py
12
+ $ touch camomilla_migrations/__init__.py
13
13
  $ python manage.py makemigrations camomilla
14
14
  $ python manage.py migrate camomilla
15
15
  ```
@@ -44,3 +44,7 @@ INSTALLED_APPS = [
44
44
 
45
45
  pip install -r requirements-dev.txt
46
46
  make test
47
+
48
+ ## Run format with black
49
+
50
+ black camomilla
@@ -1,4 +1,4 @@
1
- __version__ = "6.0.0-beta.15"
1
+ __version__ = "6.0.0-beta.17"
2
2
 
3
3
 
4
4
  def get_core_apps():
@@ -56,12 +56,12 @@ class KeepTranslationsMixin:
56
56
  )
57
57
  )
58
58
  rows = cursor.fetchall()
59
- self._saved_data_from_plain[
60
- modelPath
61
- ] = self._saved_data_from_plain.get(modelPath, {})
62
- self._saved_data_from_plain[modelPath][
63
- master[0]
64
- ] = self._saved_data_from_plain[modelPath].get(master[0], [])
59
+ self._saved_data_from_plain[modelPath] = (
60
+ self._saved_data_from_plain.get(modelPath, {})
61
+ )
62
+ self._saved_data_from_plain[modelPath][master[0]] = (
63
+ self._saved_data_from_plain[modelPath].get(master[0], [])
64
+ )
65
65
  for row in rows:
66
66
  self._saved_data_from_plain[modelPath][master[0]].append(
67
67
  dict(zip(fields, row))
@@ -83,9 +83,9 @@ class KeepTranslationsMixin:
83
83
  )
84
84
  )
85
85
  rows = cursor.fetchall()
86
- self._saved_data_from_plain[
87
- modelPath
88
- ] = self._saved_data_from_plain.get(modelPath, [])
86
+ self._saved_data_from_plain[modelPath] = (
87
+ self._saved_data_from_plain.get(modelPath, [])
88
+ )
89
89
  for row in rows:
90
90
  row_data = dict(zip(("master_id", *fields), row))
91
91
  row_data.update({"language_code": lang})
@@ -3,15 +3,19 @@ from django.urls import path
3
3
 
4
4
  from camomilla import settings
5
5
  from django.conf import settings as django_settings
6
- from .models import Page
6
+ from .models import Page, UrlRedirect
7
7
 
8
8
 
9
9
  def fetch(request, *args, **kwargs):
10
10
  can_preview = request.user.is_staff or settings.DEBUG
11
11
  preview = can_preview and request.GET.get("preview", False)
12
12
  append_slash = getattr(django_settings, "APPEND_SLASH", True)
13
+ redirect_obj = UrlRedirect.find_redirect(request)
14
+ if redirect_obj:
15
+ return redirect_obj.redirect()
13
16
  if append_slash and not request.path.endswith("/"):
14
- return redirect(request.path + "/")
17
+ q_string = request.META.get("QUERY_STRING", "")
18
+ return redirect(request.path + "/" + ("?" + q_string if q_string else ""))
15
19
  if "permalink" in kwargs:
16
20
  page = Page.get_or_404(
17
21
  request, bypass_public_check=preview, bypass_type_check=True
@@ -0,0 +1,116 @@
1
+ from django.db.models.query import QuerySet
2
+ from django.core.exceptions import ObjectDoesNotExist
3
+ from django.apps import apps
4
+ from django.db import models
5
+ from django.utils import timezone
6
+ from django.db.utils import ProgrammingError, OperationalError
7
+ from typing import Sequence, Tuple
8
+
9
+ URL_NODE_RELATED_NAME = "%(app_label)s_%(class)s"
10
+
11
+
12
+ class PageQuerySet(QuerySet):
13
+
14
+ __UrlNodeModel = None
15
+
16
+ @property
17
+ def UrlNodeModel(self):
18
+ if not self.__UrlNodeModel:
19
+ self.__UrlNodeModel = apps.get_model("camomilla", "UrlNode")
20
+ return self.__UrlNodeModel
21
+
22
+ def get_permalink_kwargs(self, kwargs):
23
+ return list(
24
+ set(kwargs.keys()).intersection(
25
+ set(self.UrlNodeModel.LANG_PERMALINK_FIELDS + ["permalink"])
26
+ )
27
+ )
28
+
29
+ def get(self, *args, **kwargs):
30
+ permalink_args = self.get_permalink_kwargs(kwargs)
31
+ if len(permalink_args):
32
+ try:
33
+ node = self.UrlNodeModel.objects.get(
34
+ **{arg: kwargs.pop(arg) for arg in permalink_args}
35
+ )
36
+ kwargs["url_node"] = node
37
+ except ObjectDoesNotExist:
38
+ raise self.model.DoesNotExist(
39
+ "%s matching query does not exist." % self.model._meta.object_name
40
+ )
41
+ return super(PageQuerySet, self).get(*args, **kwargs)
42
+
43
+
44
+ class UrlNodeManager(models.Manager):
45
+ @property
46
+ def related_names(self):
47
+ self._related_names = getattr(
48
+ self,
49
+ "_related_names",
50
+ super().get_queryset().values_list("related_name", flat=True).distinct(),
51
+ )
52
+ return self._related_names
53
+
54
+ def _annotate_fields(
55
+ self,
56
+ qs: models.QuerySet,
57
+ field_names: Sequence[Tuple[str, models.Field, models.Value]],
58
+ ):
59
+ for field_name, output_field, default in field_names:
60
+ whens = [
61
+ models.When(
62
+ related_name=related_name,
63
+ then=models.F("__".join([related_name, field_name])),
64
+ )
65
+ for related_name in self.related_names
66
+ ]
67
+ qs = qs.annotate(
68
+ **{
69
+ field_name: models.Case(
70
+ *whens, output_field=output_field, default=default
71
+ )
72
+ }
73
+ )
74
+ return self._annotate_is_public(qs)
75
+
76
+ def _annotate_is_public(self, qs: models.QuerySet):
77
+ return qs.annotate(
78
+ is_public=models.Case(
79
+ models.When(status="PUB", then=True),
80
+ models.When(
81
+ status="PLA", publication_date__lte=timezone.now(), then=True
82
+ ),
83
+ default=False,
84
+ output_field=models.BooleanField(default=False),
85
+ )
86
+ )
87
+
88
+ def get_queryset(self):
89
+ try:
90
+ return self._annotate_fields(
91
+ super().get_queryset(),
92
+ [
93
+ (
94
+ "indexable",
95
+ models.BooleanField(),
96
+ models.Value(None, models.BooleanField()),
97
+ ),
98
+ (
99
+ "status",
100
+ models.CharField(),
101
+ models.Value("DRF", models.CharField()),
102
+ ),
103
+ (
104
+ "publication_date",
105
+ models.DateTimeField(),
106
+ models.Value(timezone.now(), models.DateTimeField()),
107
+ ),
108
+ (
109
+ "date_updated_at",
110
+ models.DateTimeField(),
111
+ models.Value(timezone.now(), models.DateTimeField()),
112
+ ),
113
+ ],
114
+ )
115
+ except (ProgrammingError, OperationalError):
116
+ return super().get_queryset()
@@ -26,6 +26,7 @@ def register(
26
26
  """
27
27
 
28
28
  def inner(model):
29
+ global urlpatterns
29
30
  base_meta = {
30
31
  "model": model,
31
32
  "fields": "__all__",
@@ -47,13 +48,17 @@ def register(
47
48
  },
48
49
  )
49
50
 
51
+ def get_queryset(self, *args, **kwargs):
52
+ qs = super(base_viewset, self).get_queryset(*args, **kwargs)
53
+ return qs if filters is None else qs.filter(**filters)
54
+
50
55
  viewset = type(
51
56
  f"{model.__name__}ViewSet",
52
57
  (base_viewset,),
53
58
  {
54
- "get_queryset": lambda self: model.objects.all()
55
- if filters is None
56
- else model.objects.filter(**filters),
59
+ "queryset": model.objects.all(),
60
+ "model": model,
61
+ "get_queryset": get_queryset,
57
62
  "serializer_class": serializer,
58
63
  **viewset_attrs,
59
64
  },
@@ -61,9 +66,11 @@ def register(
61
66
 
62
67
  model_path = "".join(
63
68
  [
64
- "-" + character.lower()
65
- if character.isupper() and index > 0
66
- else character
69
+ (
70
+ "-" + character.lower()
71
+ if character.isupper() and index > 0
72
+ else character
73
+ )
67
74
  for index, character in enumerate(model.__name__)
68
75
  ]
69
76
  ).lstrip("-")
@@ -73,7 +80,7 @@ def register(
73
80
  viewset,
74
81
  f"{model.__name__.lower()}_api",
75
82
  )
76
- urlpatterns.append(path("", include(router.urls)))
83
+ urlpatterns = [path("", include(router.urls))]
77
84
  return model
78
85
 
79
86
  return inner
@@ -150,7 +150,7 @@ class Media(models.Model):
150
150
  img_bytes = self.file.storage.open(self.file.name, "rb")
151
151
  with Image.open(img_bytes) as orig_image:
152
152
  image = orig_image.copy()
153
- image.thumbnail((THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT), Image.ANTIALIAS)
153
+ image.thumbnail((THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT), Image.LANCZOS)
154
154
 
155
155
  # Path to save to, name, and extension
156
156
  thumb_name, thumb_extension = os.path.splitext(self.file.name)
@@ -14,7 +14,6 @@ from pydantic import (
14
14
  )
15
15
  from structured.pydantic.models import BaseModel
16
16
  from structured.fields import StructuredJSONField
17
- from structured.pydantic.fields import QuerySet
18
17
  from camomilla.models.page import UrlNode, AbstractPage
19
18
  from typing import Optional, Union, Callable, List
20
19
  from django.db.models.base import Model as DjangoModel
@@ -37,7 +36,9 @@ class MenuNodeLink(BaseModel):
37
36
  if self.link_type == LinkTypes.relational:
38
37
  if self.content_type and self.page:
39
38
  if isinstance(self.page, DjangoModel) and not self.page._meta.abstract:
40
- self.content_type = ContentType.objects.get_for_model(self.page.__class__)
39
+ self.content_type = ContentType.objects.get_for_model(
40
+ self.page.__class__
41
+ )
41
42
  ctype_id = getattr(self.content_type, "pk", self.content_type)
42
43
  page_id = getattr(self.page, "pk", self.page)
43
44
  c_type = ContentType.objects.filter(pk=ctype_id).first()
@@ -47,7 +48,9 @@ class MenuNodeLink(BaseModel):
47
48
  elif self.url_node:
48
49
  url_node_id = getattr(self.url_node, "pk", self.url_node)
49
50
  self.page = UrlNode.objects.filter(pk=url_node_id).first().page
50
- self.content_type = ContentType.objects.get_for_model(self.page.__class__)
51
+ self.content_type = ContentType.objects.get_for_model(
52
+ self.page.__class__
53
+ )
51
54
  return handler(self)
52
55
 
53
56
  def get_url(self, request=None):
@@ -88,7 +91,10 @@ class Menu(models.Model):
88
91
  ):
89
92
  if isinstance(context, RequestContext):
90
93
  context = context.flatten()
91
- context.update({"menu": self})
94
+ is_preview = (
95
+ False if request is None else bool(request.GET.get("preview", False))
96
+ )
97
+ context.update({"menu": self, "is_preview": is_preview})
92
98
  return mark_safe(render_to_string(template_path, context, request))
93
99
 
94
100
  class defaultdict(dict):