django-camomilla-cms 6.0.0b16__py2.py3-none-any.whl → 6.0.0b17__py2.py3-none-any.whl
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.
- camomilla/__init__.py +1 -1
- camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
- camomilla/dynamic_pages_urls.py +6 -2
- camomilla/managers/pages.py +87 -2
- camomilla/model_api.py +6 -4
- camomilla/models/menu.py +9 -4
- camomilla/models/page.py +178 -117
- camomilla/openapi/schema.py +15 -10
- camomilla/redirects.py +10 -0
- camomilla/serializers/base/__init__.py +4 -4
- camomilla/serializers/fields/__init__.py +5 -17
- camomilla/serializers/fields/related.py +5 -3
- camomilla/serializers/mixins/__init__.py +23 -240
- camomilla/serializers/mixins/fields.py +20 -0
- camomilla/serializers/mixins/filter_fields.py +9 -8
- camomilla/serializers/mixins/json.py +34 -0
- camomilla/serializers/mixins/language.py +32 -0
- camomilla/serializers/mixins/nesting.py +35 -0
- camomilla/serializers/mixins/optimize.py +91 -0
- camomilla/serializers/mixins/ordering.py +34 -0
- camomilla/serializers/mixins/page.py +58 -0
- camomilla/{contrib/rest_framework/serializer.py → serializers/mixins/translation.py} +16 -56
- camomilla/serializers/utils.py +3 -3
- camomilla/serializers/validators.py +6 -2
- camomilla/settings.py +10 -2
- camomilla/storages/default.py +7 -1
- camomilla/templates/defaults/parts/menu.html +1 -1
- camomilla/templatetags/menus.py +3 -0
- camomilla/theme/__init__.py +1 -1
- camomilla/theme/{admin.py → admin/__init__.py} +22 -20
- camomilla/theme/admin/pages.py +46 -0
- camomilla/theme/admin/translations.py +13 -0
- camomilla/theme/apps.py +1 -5
- camomilla/translation.py +7 -1
- camomilla/urls.py +2 -5
- camomilla/utils/query_parser.py +42 -23
- camomilla/utils/translation.py +47 -5
- camomilla/views/base/__init__.py +35 -5
- camomilla/views/medias.py +1 -1
- camomilla/views/mixins/__init__.py +17 -76
- camomilla/views/mixins/bulk_actions.py +22 -0
- camomilla/views/mixins/language.py +33 -0
- camomilla/views/mixins/optimize.py +18 -0
- camomilla/views/mixins/pagination.py +11 -8
- camomilla/views/mixins/permissions.py +6 -0
- camomilla/views/pages.py +12 -2
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA +23 -16
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/RECORD +60 -43
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/WHEEL +1 -1
- tests/test_camomilla_filters.py +1 -1
- tests/test_media.py +98 -65
- tests/test_menu.py +97 -0
- tests/test_model_api_register.py +393 -0
- tests/test_pages.py +343 -0
- tests/test_query_parser.py +1 -2
- tests/test_templates_context.py +111 -0
- tests/utils/api.py +0 -1
- tests/utils/media.py +9 -0
- camomilla/contrib/rest_framework/__init__.py +0 -0
- camomilla/serializers/fields/json.py +0 -48
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info/licenses}/LICENSE +0 -0
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/top_level.txt +0 -0
camomilla/views/base/__init__.py
CHANGED
@@ -1,8 +1,38 @@
|
|
1
|
-
from ..mixins import
|
1
|
+
from ..mixins import (
|
2
|
+
OptimViewMixin,
|
3
|
+
PaginateStackMixin,
|
4
|
+
OrderingMixin,
|
5
|
+
CamomillaBasePermissionMixin,
|
6
|
+
)
|
2
7
|
from rest_framework import viewsets
|
8
|
+
from rest_framework.metadata import SimpleMetadata
|
9
|
+
from structured.contrib.restframework import StructuredJSONField
|
3
10
|
|
4
11
|
|
5
|
-
|
6
|
-
CamomillaBasePermissionMixin,
|
7
|
-
|
8
|
-
|
12
|
+
base_viewset_classes = [
|
13
|
+
CamomillaBasePermissionMixin,
|
14
|
+
OptimViewMixin,
|
15
|
+
OrderingMixin,
|
16
|
+
PaginateStackMixin,
|
17
|
+
viewsets.ModelViewSet,
|
18
|
+
]
|
19
|
+
|
20
|
+
|
21
|
+
class BaseViewMetadata(SimpleMetadata):
|
22
|
+
|
23
|
+
def get_field_info(self, field):
|
24
|
+
field_info = super().get_field_info(field)
|
25
|
+
if isinstance(field, StructuredJSONField):
|
26
|
+
field_info["schema"] = field.schema.json_schema()
|
27
|
+
field_info["type"] = "structured-json"
|
28
|
+
return field_info
|
29
|
+
|
30
|
+
def get_serializer_info(self, serializer):
|
31
|
+
info = super().get_serializer_info(serializer)
|
32
|
+
if hasattr(serializer, "plain_to_nest"):
|
33
|
+
info.update(serializer.plain_to_nest(info))
|
34
|
+
return info
|
35
|
+
|
36
|
+
|
37
|
+
class BaseModelViewset(*base_viewset_classes):
|
38
|
+
metadata_class = BaseViewMetadata
|
camomilla/views/medias.py
CHANGED
@@ -1,76 +1,17 @@
|
|
1
|
-
from
|
2
|
-
from
|
3
|
-
from
|
4
|
-
from .
|
5
|
-
from .
|
6
|
-
from
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
self.language_fallbacks = True
|
19
|
-
if (
|
20
|
-
len(self.active_language.split("-")) == 2
|
21
|
-
and self.active_language.split("-")[0] == "nofallbacks"
|
22
|
-
):
|
23
|
-
self.language_fallbacks = False
|
24
|
-
self.active_language = self.active_language.split("-")[1]
|
25
|
-
translation.activate(self.active_language)
|
26
|
-
return self.active_language
|
27
|
-
|
28
|
-
def initialize_request(self, request, *args, **kwargs):
|
29
|
-
self._get_user_language(request)
|
30
|
-
return super().initialize_request(request, *args, **kwargs)
|
31
|
-
|
32
|
-
def get_queryset(self):
|
33
|
-
if hasattr(super(), "get_queryset"):
|
34
|
-
return super().get_queryset()
|
35
|
-
return self.model.objects.all()
|
36
|
-
|
37
|
-
|
38
|
-
class CamomillaBasePermissionMixin:
|
39
|
-
def get_permissions(self):
|
40
|
-
return [*super().get_permissions(), CamomillaBasePermissions()]
|
41
|
-
|
42
|
-
|
43
|
-
class OptimViewMixin:
|
44
|
-
def get_serializer_class(self):
|
45
|
-
if hasattr(self, "action_serializers"):
|
46
|
-
if self.action in self.action_serializers:
|
47
|
-
return self.action_serializers[self.action]
|
48
|
-
return super().get_serializer_class()
|
49
|
-
|
50
|
-
def get_serializer_context(self):
|
51
|
-
return {"request": self.request, "action": self.action}
|
52
|
-
|
53
|
-
def get_queryset(self):
|
54
|
-
queryset = super().get_queryset()
|
55
|
-
serializer = self.get_serializer_class()
|
56
|
-
if hasattr(serializer, "optimize_qs"):
|
57
|
-
queryset = serializer.optimize_qs(queryset, context=self.get_serializer_context())
|
58
|
-
return queryset
|
59
|
-
|
60
|
-
|
61
|
-
class BulkDeleteMixin(object):
|
62
|
-
@action(
|
63
|
-
detail=False, methods=["post"], permission_classes=(CamomillaBasePermissions,)
|
64
|
-
)
|
65
|
-
def bulk_delete(self, request):
|
66
|
-
try:
|
67
|
-
self.model.objects.filter(pk__in=request.data).delete()
|
68
|
-
return Response(
|
69
|
-
{"detail": "Eliminazione multipla andata a buon fine"},
|
70
|
-
status=status.HTTP_200_OK,
|
71
|
-
)
|
72
|
-
except Exception:
|
73
|
-
return Response(
|
74
|
-
{"detail": "Eliminazione multipla non riuscita"},
|
75
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
76
|
-
)
|
1
|
+
from .bulk_actions import BulkDeleteMixin
|
2
|
+
from .language import GetUserLanguageMixin
|
3
|
+
from .optimize import OptimViewMixin
|
4
|
+
from .ordering import OrderingMixin
|
5
|
+
from .pagination import PaginateStackMixin, TrigramSearchMixin
|
6
|
+
from .permissions import CamomillaBasePermissionMixin
|
7
|
+
|
8
|
+
|
9
|
+
__all__ = [
|
10
|
+
"BulkDeleteMixin",
|
11
|
+
"GetUserLanguageMixin",
|
12
|
+
"OptimViewMixin",
|
13
|
+
"OrderingMixin",
|
14
|
+
"PaginateStackMixin",
|
15
|
+
"TrigramSearchMixin",
|
16
|
+
"CamomillaBasePermissionMixin",
|
17
|
+
]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from rest_framework import status
|
2
|
+
from rest_framework.decorators import action
|
3
|
+
from rest_framework.response import Response
|
4
|
+
from ...permissions import CamomillaBasePermissions
|
5
|
+
|
6
|
+
|
7
|
+
class BulkDeleteMixin(object):
|
8
|
+
@action(
|
9
|
+
detail=False, methods=["post"], permission_classes=(CamomillaBasePermissions,)
|
10
|
+
)
|
11
|
+
def bulk_delete(self, request):
|
12
|
+
try:
|
13
|
+
self.model.objects.filter(pk__in=request.data).delete()
|
14
|
+
return Response(
|
15
|
+
{"detail": "Eliminazione multipla andata a buon fine"},
|
16
|
+
status=status.HTTP_200_OK,
|
17
|
+
)
|
18
|
+
except Exception:
|
19
|
+
return Response(
|
20
|
+
{"detail": "Eliminazione multipla non riuscita"},
|
21
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
22
|
+
)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from django.utils import translation
|
2
|
+
from camomilla import settings
|
3
|
+
|
4
|
+
|
5
|
+
class GetUserLanguageMixin:
|
6
|
+
def _get_user_language(self, request):
|
7
|
+
active_language_from_request = translation.get_language_from_request(request)
|
8
|
+
active_language = (
|
9
|
+
active_language_from_request
|
10
|
+
if active_language_from_request
|
11
|
+
else settings.DEFAULT_LANGUAGE
|
12
|
+
)
|
13
|
+
active_language = request.GET.get("language_code", active_language)
|
14
|
+
active_language = request.GET.get("language", active_language)
|
15
|
+
self.active_language = active_language
|
16
|
+
self.language_fallbacks = True
|
17
|
+
if (
|
18
|
+
len(self.active_language.split("-")) == 2
|
19
|
+
and self.active_language.split("-")[0] == "nofallbacks"
|
20
|
+
):
|
21
|
+
self.language_fallbacks = False
|
22
|
+
self.active_language = self.active_language.split("-")[1]
|
23
|
+
translation.activate(self.active_language)
|
24
|
+
return self.active_language
|
25
|
+
|
26
|
+
def initialize_request(self, request, *args, **kwargs):
|
27
|
+
self._get_user_language(request)
|
28
|
+
return super().initialize_request(request, *args, **kwargs)
|
29
|
+
|
30
|
+
def get_queryset(self):
|
31
|
+
if hasattr(super(), "get_queryset"):
|
32
|
+
return super().get_queryset()
|
33
|
+
return self.model.objects.all()
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class OptimViewMixin:
|
2
|
+
def get_serializer_class(self):
|
3
|
+
if hasattr(self, "action_serializers"):
|
4
|
+
if self.action in self.action_serializers:
|
5
|
+
return self.action_serializers[self.action]
|
6
|
+
return super().get_serializer_class()
|
7
|
+
|
8
|
+
def get_serializer_context(self):
|
9
|
+
return {"request": self.request, "action": self.action}
|
10
|
+
|
11
|
+
def get_queryset(self):
|
12
|
+
queryset = super().get_queryset()
|
13
|
+
serializer = self.get_serializer_class()
|
14
|
+
if hasattr(serializer, "optimize_qs"):
|
15
|
+
queryset = serializer.optimize_qs(
|
16
|
+
queryset, context=self.get_serializer_context()
|
17
|
+
)
|
18
|
+
return queryset
|
@@ -3,6 +3,7 @@ from django.db.models import Q
|
|
3
3
|
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
4
4
|
from django.contrib.postgres.search import SearchVector, SearchQuery, TrigramSimilarity
|
5
5
|
from camomilla.utils.query_parser import ConditionParser
|
6
|
+
from django.conf import settings
|
6
7
|
|
7
8
|
|
8
9
|
class TrigramSearchMixin:
|
@@ -33,10 +34,6 @@ class PaginateStackMixin:
|
|
33
34
|
list_handler, "shared_model", getattr(list_handler, "model", None)
|
34
35
|
)
|
35
36
|
|
36
|
-
def parse_filter(self, filter):
|
37
|
-
parser = ConditionParser(filter)
|
38
|
-
return parser.parse_to_q()
|
39
|
-
|
40
37
|
def handle_pagination(self, list_handler=None, items_per_page=None):
|
41
38
|
list_handler = list_handler if list_handler is not None else self.get_queryset()
|
42
39
|
items_per_page = int(
|
@@ -76,7 +73,7 @@ class PaginateStackMixin:
|
|
76
73
|
filters = dict(self.request.GET).get("fltr", [])
|
77
74
|
for filter in filters:
|
78
75
|
try:
|
79
|
-
list_handler = list_handler.filter(
|
76
|
+
list_handler = list_handler.filter(ConditionParser(filter).db_query)
|
80
77
|
except Exception:
|
81
78
|
pass
|
82
79
|
return list_handler
|
@@ -86,9 +83,15 @@ class PaginateStackMixin:
|
|
86
83
|
search_string = self.request.GET.get("search", None)
|
87
84
|
search_fields = search_fields or getattr(self, "search_fields", [])
|
88
85
|
if search_string and len(search_fields) > 0:
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
if "sqlite" in settings.DATABASES["default"]["ENGINE"]:
|
87
|
+
filter_statement = Q()
|
88
|
+
for field in search_fields:
|
89
|
+
filter_statement |= Q(**{field + '__icontains': search_string})
|
90
|
+
return list_handler.filter(filter_statement)
|
91
|
+
else:
|
92
|
+
return list_handler.annotate(
|
93
|
+
search=SearchVector(*search_fields),
|
94
|
+
).filter(search=SearchQuery(search_string))
|
92
95
|
|
93
96
|
return list_handler
|
94
97
|
|
camomilla/views/pages.py
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
from camomilla.models import Page
|
2
|
-
from camomilla.models.page import UrlNode
|
2
|
+
from camomilla.models.page import UrlNode, UrlRedirect
|
3
3
|
from camomilla.permissions import CamomillaBasePermissions
|
4
4
|
from camomilla.serializers import PageSerializer
|
5
5
|
from camomilla.serializers.page import UrlNodeSerializer
|
6
6
|
from camomilla.views.base import BaseModelViewset
|
7
7
|
from camomilla.views.decorators import active_lang
|
8
8
|
from camomilla.views.mixins import BulkDeleteMixin, GetUserLanguageMixin
|
9
|
-
from rest_framework.decorators import api_view
|
9
|
+
from rest_framework.decorators import api_view, permission_classes
|
10
10
|
from rest_framework.response import Response
|
11
|
+
from rest_framework import permissions
|
11
12
|
from django.shortcuts import get_object_or_404
|
12
13
|
|
13
14
|
|
@@ -20,6 +21,15 @@ class PageViewSet(GetUserLanguageMixin, BulkDeleteMixin, BaseModelViewset):
|
|
20
21
|
|
21
22
|
@active_lang()
|
22
23
|
@api_view(["GET"])
|
24
|
+
@permission_classes(
|
25
|
+
[
|
26
|
+
permissions.AllowAny,
|
27
|
+
]
|
28
|
+
)
|
23
29
|
def fetch_page(request, permalink=""):
|
30
|
+
redirect = UrlRedirect.find_redirect_from_url(f"/{permalink}")
|
31
|
+
if redirect:
|
32
|
+
redirect = redirect.redirect()
|
33
|
+
return Response({"redirect": redirect.url, "status": redirect.status_code})
|
24
34
|
node = get_object_or_404(UrlNode, permalink=f"/{permalink}")
|
25
35
|
return Response(UrlNodeSerializer(node, context={"request": request}).data)
|
{django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA
RENAMED
@@ -1,30 +1,33 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: django-camomilla-cms
|
3
|
-
Version: 6.0.
|
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/
|
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:
|
14
|
+
Requires-Python: <=3.13,>=3.8
|
15
15
|
Description-Content-Type: text/markdown
|
16
16
|
License-File: LICENSE
|
17
|
-
Requires-Dist: django-modeltranslation
|
18
|
-
Requires-Dist: djsuperadmin
|
19
|
-
Requires-Dist: djangorestframework
|
20
|
-
Requires-Dist: django-
|
21
|
-
Requires-Dist: Pillow
|
22
|
-
Requires-Dist: django-
|
23
|
-
Requires-Dist: django-
|
24
|
-
Requires-Dist:
|
25
|
-
Requires-Dist:
|
26
|
-
|
27
|
-
|
17
|
+
Requires-Dist: django-modeltranslation<=0.18.12,>=0.18.7
|
18
|
+
Requires-Dist: djsuperadmin<1.0.0,>=0.9
|
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
|
22
|
+
Requires-Dist: django-admin-interface<1.0.0,>=0.26.0
|
23
|
+
Requires-Dist: django-ckeditor<7.0.0,>=5.7.1
|
24
|
+
Requires-Dist: django-tinymce<5.0.0,>=4.1.0
|
25
|
+
Requires-Dist: python-magic<0.5,>=0.4
|
26
|
+
Requires-Dist: Django<6,>=3.2
|
27
|
+
Requires-Dist: django_jsonform>=2.23
|
28
|
+
Dynamic: license-file
|
29
|
+
|
30
|
+
# camomilla django cms [](https://pypi.org/project/django-camomilla-cms)   [](./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
|
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,38 +1,37 @@
|
|
1
|
-
camomilla/__init__.py,sha256=
|
1
|
+
camomilla/__init__.py,sha256=xH1i4zwYfJScQn-ySoem00poi295diBqrVChxqcmkW8,251
|
2
2
|
camomilla/apps.py,sha256=eUwb9ynyiRAc5OXgt7ZsAdhsCOnPCpNdIFYMheNeN-o,532
|
3
3
|
camomilla/authentication.py,sha256=jz6tQT4PPEu-_JLox1LZrOy7EiWBb9MWaObK63MJGus,855
|
4
4
|
camomilla/context_processors.py,sha256=cGowjDZ-oDGYn1j2Pj5QDGCqnzXAOdOwp5dmzin_FTc,165
|
5
5
|
camomilla/defaults.py,sha256=VNQ_sbxu09AyFGNpUUYypIAyhlBhEORD36BBNj7e73I,1220
|
6
|
-
camomilla/dynamic_pages_urls.py,sha256=
|
6
|
+
camomilla/dynamic_pages_urls.py,sha256=wd52ktpY_LH24jTW77vII7XZ25p_Kz5MSjes8s_94-A,1278
|
7
7
|
camomilla/exceptions.py,sha256=gLniAsK_pmsNNKGMv5Z384LXVbM8oeHcOwz4F91u1LY,111
|
8
|
-
camomilla/model_api.py,sha256
|
8
|
+
camomilla/model_api.py,sha256=-7l3fc2eN1itCMzkWA8nFaQXMmz0vs7IlGlShF-gSuo,2487
|
9
9
|
camomilla/parsers.py,sha256=fL8XGCGPxJIZNZkPdGtnPSbDP-6-yzGOCVMuLPjkx9Y,1975
|
10
10
|
camomilla/permissions.py,sha256=9NlBO4JMmg36vXCUjPNyq6uZxhkdrnXyIbJVLtWhGWE,1813
|
11
|
-
camomilla/
|
11
|
+
camomilla/redirects.py,sha256=ilcyHidb5Iw3jTrXMnPntr50kkl_WB3QOB0VNkIxP7A,263
|
12
|
+
camomilla/settings.py,sha256=nY-a1PRhbQ_edvNG5WyndPLWxwsRb_h4eFAjmOHvKYM,3599
|
12
13
|
camomilla/sitemap.py,sha256=U2t5TwhB_-sEscmQZ69PZ5st3bIap8NRxzWEvCgB130,786
|
13
|
-
camomilla/translation.py,sha256
|
14
|
-
camomilla/urls.py,sha256=
|
14
|
+
camomilla/translation.py,sha256=_QyfTlKG6hQ_ClRfxzeJ-3oI3Nu5peJN9xFkO9Ib3As,1316
|
15
|
+
camomilla/urls.py,sha256=XgaeFoG2eXlJQve3KmFKlD-74CMLW1ziaY1mq-lrAiA,2095
|
15
16
|
camomilla/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
17
|
camomilla/contrib/modeltranslation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
camomilla/contrib/modeltranslation/hvad_migration.py,sha256=
|
18
|
-
camomilla/contrib/rest_framework/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
camomilla/contrib/rest_framework/serializer.py,sha256=G6SKes-8RkJKDupCNN0B2B1BQuYqS0y820oGYotxPcY,5924
|
18
|
+
camomilla/contrib/modeltranslation/hvad_migration.py,sha256=3j_q_Q85eF4iHbU4LG1Zr3LOmfmGmFiVSL-C8KvPsJQ,5409
|
20
19
|
camomilla/fields/__init__.py,sha256=gKrJwHvUA3q_wu-OVV0hrRZmFkT4znMHrmZtpriDumw,323
|
21
20
|
camomilla/fields/json.py,sha256=tWEDn6kwTP6pNB53djxuVPu2d57m9cIDc4ccCEfUbDQ,1938
|
22
21
|
camomilla/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
22
|
camomilla/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
23
|
camomilla/management/commands/regenerate_thumbnails.py,sha256=pKToASR8p8TJezGpFfuylsAHtriNueJ7xqJJxq55adY,496
|
25
24
|
camomilla/managers/__init__.py,sha256=Zwp28E1RKafIl0FqcUi1YNHxF19IsMIvhlhS-Njg9Mw,60
|
26
|
-
camomilla/managers/pages.py,sha256=
|
25
|
+
camomilla/managers/pages.py,sha256=DYV1i5vPgxn1YzJlY3kSlsVCRgsiojLxjs2O0LylxEI,3925
|
27
26
|
camomilla/models/__init__.py,sha256=y7Q34AGhQ1weJUKWb6XjiyUbwRnJeylOBGMErU0wqYg,147
|
28
27
|
camomilla/models/article.py,sha256=LgkZgRsubtDV6NwBz8E2bIgKD6H3I-1QLAxEan5TYYs,1139
|
29
28
|
camomilla/models/content.py,sha256=mIgtifb_WMIt58we5u6qWZemHvuDN1zZaBeCyzHL78A,956
|
30
29
|
camomilla/models/media.py,sha256=pD-qldiHDOOHgux4lsivQLBcOJJrRx3a4Bg8ODNx7r0,6852
|
31
|
-
camomilla/models/menu.py,sha256=
|
32
|
-
camomilla/models/page.py,sha256=
|
30
|
+
camomilla/models/menu.py,sha256=hUszPcn1prWCDhk4RPvbITmyhsB2CjFkaerx9t1GWnc,3766
|
31
|
+
camomilla/models/page.py,sha256=lkZPdPkl8Yxpz_NfYrpr7Myp8hB3bEAGtdJwKBR7_cg,19385
|
33
32
|
camomilla/models/mixins/__init__.py,sha256=c2NixqvrIX4E9WGRqQbylXlqBWDXEqN9mzs_dpB0hFQ,1248
|
34
33
|
camomilla/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
camomilla/openapi/schema.py,sha256=
|
34
|
+
camomilla/openapi/schema.py,sha256=C22dhKjaJ2DTK4KWFjyMJXiwe8NLy7ZTW5d-I1dqZ7g,2546
|
36
35
|
camomilla/serializers/__init__.py,sha256=8v1GsJ_YZ6T72VnKBb5l-8K93oaLf4PIsMt-yFtK-Gk,176
|
37
36
|
camomilla/serializers/article.py,sha256=pYVcS0KztzjzSqgruElQMMEZcqTzmQUqXrdv_Sx5Az4,401
|
38
37
|
camomilla/serializers/content_type.py,sha256=qB2wkmkvQI6LHxfSI6auEh6M9cJRFBaHnpmkBCCzeYo,557
|
@@ -40,17 +39,24 @@ camomilla/serializers/media.py,sha256=H4JVpRVxXVmn_BiqrjihKXpfLm9fLmHDFIICRDGJU4
|
|
40
39
|
camomilla/serializers/menu.py,sha256=TdoyXs40PqxNevnRbBbYOOX9rUv9zQGiHFNduspaZnw,552
|
41
40
|
camomilla/serializers/page.py,sha256=NNjEypVYu_9iKqdHV_-61ea37gxiHlDP5gsloV_i6yg,1834
|
42
41
|
camomilla/serializers/user.py,sha256=CzrHiVRvYYWNE4eNpCNKtJB7DjVqHHwIcP4NUBXMHSo,3706
|
43
|
-
camomilla/serializers/utils.py,sha256=
|
44
|
-
camomilla/serializers/validators.py,sha256=
|
45
|
-
camomilla/serializers/base/__init__.py,sha256=
|
46
|
-
camomilla/serializers/fields/__init__.py,sha256=
|
42
|
+
camomilla/serializers/utils.py,sha256=XRL4CNwQDBNpX8xT7365Dw2Cyx8Kvh18GaadgjS9awk,968
|
43
|
+
camomilla/serializers/validators.py,sha256=X2uBlh348nJjUWHPtiu9XKCD7Etsdg0811a4xHLAUzU,2103
|
44
|
+
camomilla/serializers/base/__init__.py,sha256=maaL3y6tvc5Ph9y07KVcMvZVYTkzh_3aBiBnGCoi1EA,799
|
45
|
+
camomilla/serializers/fields/__init__.py,sha256=0I_E9oMtlC0H48LjStMQZiZ-Ycoy49nWK9GvA5JWxN8,145
|
47
46
|
camomilla/serializers/fields/file.py,sha256=yjKMho2ti9TIAzo6nwyLnNPJ6GVUumL2wxhegvYqI2o,800
|
48
|
-
camomilla/serializers/fields/
|
49
|
-
camomilla/serializers/
|
50
|
-
camomilla/serializers/mixins/
|
51
|
-
camomilla/serializers/mixins/filter_fields.py,sha256=
|
47
|
+
camomilla/serializers/fields/related.py,sha256=qQQeUxIZSNqnVRHsXocLGmBNHjAvrlr0eDY9K2uCjWk,5069
|
48
|
+
camomilla/serializers/mixins/__init__.py,sha256=gMyFpSWHLtLTlKucP1Xk-GtBNX48CwwyY6_wEN3L9vA,640
|
49
|
+
camomilla/serializers/mixins/fields.py,sha256=h-YBHBITLGHsrXRgSYP3NBoUzJqmQ_5HhhftoFFNsKs,711
|
50
|
+
camomilla/serializers/mixins/filter_fields.py,sha256=sqnCG1hi_qfISFJvwgh37BLyQoNDifR0pU7zmJn_MW8,2236
|
51
|
+
camomilla/serializers/mixins/json.py,sha256=Iq5S7mUg5_Y4bsm6XN3ECJR07NGjCAQ21_wdxj6RgyY,1193
|
52
|
+
camomilla/serializers/mixins/language.py,sha256=VukEvPzTpKQfwB-z_RtoNIJ43N3OEgfjLpHvn9KuZDU,1205
|
53
|
+
camomilla/serializers/mixins/nesting.py,sha256=gCEU2UE_Y8e4VRnvT0AExFgwTfJm_jnSqa6l2SwZ3Mg,1432
|
54
|
+
camomilla/serializers/mixins/optimize.py,sha256=zAtbtk6kfGq9FnapqI8tVYOuMKd1IkHbAV6LffL61Z4,3845
|
55
|
+
camomilla/serializers/mixins/ordering.py,sha256=rXQOz47_U4IsMT6IBhySghcmJWMZgpPWHovDcZQG88k,1172
|
56
|
+
camomilla/serializers/mixins/page.py,sha256=Ida7dY9MQTv747_dpPGpo6u3iL5GX87z4zeVct-C36s,2132
|
57
|
+
camomilla/serializers/mixins/translation.py,sha256=Om2UT2EB4Xvp8SrIEvraY0kJXR9H54AsYBr9DKjsay8,4323
|
52
58
|
camomilla/storages/__init__.py,sha256=ytGgX59Ar8vFfYz7eV8z-j5yO_5FqxdZM25iyLnJuSA,131
|
53
|
-
camomilla/storages/default.py,sha256=
|
59
|
+
camomilla/storages/default.py,sha256=GNzvV_JZpXMcfTkyXjw5CfK8EIBi3o-NXYBO0KAxD5M,351
|
54
60
|
camomilla/storages/optimize.py,sha256=VGSXZigzZC8LnPTqyTOpPA2Ba9EJB_KC5bcACoRs4GA,2762
|
55
61
|
camomilla/storages/overwrite.py,sha256=jvW3zHvXNzH9dIjeZmmfXo_O3K1ZQmLQzmlSKAOE8ZA,360
|
56
62
|
camomilla/templates/admin/camomilla/page/change_form.html,sha256=ig7rRUtylDZMINBQuVPpZLmeB4sOTV_VtqnTgzAyxEo,251
|
@@ -58,17 +64,19 @@ camomilla/templates/defaults/base.html,sha256=pklt7Pif3g9d7gwgRxCQj7gniJaHD14ZqZ
|
|
58
64
|
camomilla/templates/defaults/articles/default.html,sha256=1f89jBvNtTa1mPAbC91yy8CzeAjTWO3hhQsTuQW5OKg,239
|
59
65
|
camomilla/templates/defaults/pages/default.html,sha256=bP81Qb6M56I-fBJMywWwEu_cnERtWIX28UkGrUSRU6M,144
|
60
66
|
camomilla/templates/defaults/parts/langswitch.html,sha256=AkaQzb2KNjRYCMLUn_jE31V36rwBIwp4MneirWPiBcI,3424
|
61
|
-
camomilla/templates/defaults/parts/menu.html,sha256=
|
67
|
+
camomilla/templates/defaults/parts/menu.html,sha256=ReE-FfmfCNuNkJI33QqIfmMgLSBl3FTkWAhEa59aD3A,381
|
62
68
|
camomilla/templates/defaults/widgets/media_select_multiple.html,sha256=k2XYou8KkPuFLnPMkPJAFJ-zGJj2Xvu6R3ZmiKa3g7Q,3727
|
63
69
|
camomilla/templates_context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
70
|
camomilla/templates_context/autodiscover.py,sha256=td7SCsqg3iNPnv1HDEDEpwWgWLjy5Zmc8Nbze1_J46I,1907
|
65
71
|
camomilla/templates_context/rendering.py,sha256=GfTR45_gC7WT7zTKPVXkBDwe22uF63A-DfZUW31woAU,3194
|
66
72
|
camomilla/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
73
|
camomilla/templatetags/camomilla_filters.py,sha256=35x0-cWrRHeLhqypSLlJzEFY_fQDcRHiwZQpFgIsspE,692
|
68
|
-
camomilla/templatetags/menus.py,sha256=
|
69
|
-
camomilla/theme/__init__.py,sha256=
|
70
|
-
camomilla/theme/
|
71
|
-
camomilla/theme/
|
74
|
+
camomilla/templatetags/menus.py,sha256=7fc4f9DDqtqG6wNb5_Q0km-fq0mqvGnbpR21qO1TJUw,960
|
75
|
+
camomilla/theme/__init__.py,sha256=3ahSYJ-HBLHrW2VZ45mAM6mlZvpqDKPffxhE0EkD9as,30
|
76
|
+
camomilla/theme/apps.py,sha256=3nCSZ6d4tkx2aMNNnQQoqX8PGrrMNf4VxCxBV_JXNrA,1040
|
77
|
+
camomilla/theme/admin/__init__.py,sha256=TALAZaE-gWshSeGc6yy7VahdX5UfeCeoOE9Q5kJCEpM,2270
|
78
|
+
camomilla/theme/admin/pages.py,sha256=y3rL1nwZlytyD-YR_qqLiBAmjCAjkBY3v56V6JdhBvY,1908
|
79
|
+
camomilla/theme/admin/translations.py,sha256=iAjGM1A1aYrsz1FpeybROk6rn3Ddl_oUCwgU5oD8nSw,308
|
72
80
|
camomilla/theme/static/admin/css/responsive.css,sha256=yGq6qXrr8xEVsXTnprIBgkX-sMGZrNf0Kkh-xDxf6yE,157
|
73
81
|
camomilla/theme/static/admin/img/favicon.ico,sha256=qpKv_2MaGILvyihnD1Vq9Yk-ZXGkxWTW26ciMeBFMYU,15406
|
74
82
|
camomilla/theme/static/admin/img/logo.svg,sha256=WBAORIV_LzEOdcpq7iU6d0Nu3omgk2gn05f6LnPjfWg,3238
|
@@ -77,39 +85,48 @@ camomilla/theme/templates/rosetta/base.html,sha256=s9Ijf1nZx8um30R5Gk3g-w-RwFGv2
|
|
77
85
|
camomilla/utils/__init__.py,sha256=Ui7nzSh45UMMFtCGF1xFHKyJMNWflG_Nx72HAJHJHFM,100
|
78
86
|
camomilla/utils/getters.py,sha256=6j18grFAZ8BC70SriycFDTQFxTnudGn0uKGA83_Rclk,798
|
79
87
|
camomilla/utils/normalization.py,sha256=RDCZtjwpEEwjvfUjQl2bEWFKw7NxTzkXco72VeO2M9w,255
|
80
|
-
camomilla/utils/query_parser.py,sha256=
|
88
|
+
camomilla/utils/query_parser.py,sha256=TUScPzPVVJzaKdqy5NqtMOft3H5Bx6liXTVPM1yjH24,6303
|
81
89
|
camomilla/utils/seo.py,sha256=8p_a_TGgohenpJb094tT4mMxbn2xzW0qDILuTnjNocM,3324
|
82
90
|
camomilla/utils/setters.py,sha256=LV57SM65rL1_ZQkVzk9al_Q13lndVywXLkqgfIvgS0Y,915
|
83
91
|
camomilla/utils/templates.py,sha256=Lv4-5019cnM30HmdZnYWiU5gxry-eFZVAhwOofGQRDs,598
|
84
|
-
camomilla/utils/translation.py,sha256=
|
92
|
+
camomilla/utils/translation.py,sha256=w5tvTInDLegWBb1TnDWo09ckKY3K6hajuNNsngZIxPQ,4205
|
85
93
|
camomilla/views/__init__.py,sha256=94QuOnnbfMMb17mruO2ydUt286-8zBmDxEPWrJv5Wog,178
|
86
94
|
camomilla/views/articles.py,sha256=qGxebOA5iTbGGe9PfbH40YBoDPKktH8FJongg6rh2R8,571
|
87
95
|
camomilla/views/contents.py,sha256=JxvnmgeK8JEmCMLzVG8pVq2DwvmjXtgnIdsDnn74tA4,1205
|
88
96
|
camomilla/views/decorators.py,sha256=hR--nTGQn2mMKDrWn-0Ildzbsvp11OfoWAtedKEzmiA,982
|
89
97
|
camomilla/views/languages.py,sha256=Rt_X7s3dbDBv4dxsQ9fnav_u0TAzzo8fGKBBx3esDsg,441
|
90
|
-
camomilla/views/medias.py,sha256=
|
98
|
+
camomilla/views/medias.py,sha256=XYa-NTLLQmSSynpfrFT3av-K_r59aRns3dTGfYMj-0Q,3002
|
91
99
|
camomilla/views/menus.py,sha256=Kpygnf3tMKJ30gcblUES2NW83A37Vy75ecSGSvExGKM,3301
|
92
|
-
camomilla/views/pages.py,sha256=
|
100
|
+
camomilla/views/pages.py,sha256=UL74_u-18QdAkjVl74AVWZbRarEdIPrANTzdcM4iqmE,1338
|
93
101
|
camomilla/views/tags.py,sha256=XcYRlcBFSPPY32lt7POb6fWPJL_8HsTo5JcHcAOiOKw,479
|
94
102
|
camomilla/views/users.py,sha256=_fvsKOEtep4SJLvMva2_q-HdLQT_1KlFNt4wcl3xCJk,3130
|
95
|
-
camomilla/views/base/__init__.py,sha256=
|
96
|
-
camomilla/views/mixins/__init__.py,sha256=
|
103
|
+
camomilla/views/base/__init__.py,sha256=t-7tqY_ep4Xi8YgB1sXDgNWQ5oh2YEUlfQWU5pltwJ0,1063
|
104
|
+
camomilla/views/mixins/__init__.py,sha256=Znv3fLYVy6lgu03Q_D8fTen4zMxI6VSRaLPDU8Cp7Ws,473
|
105
|
+
camomilla/views/mixins/bulk_actions.py,sha256=i0duWW6wey9m7I_V8-gPcHsbJyPEfSdMdj4h2i-CbPw,787
|
106
|
+
camomilla/views/mixins/language.py,sha256=hfnYznlVMrMLBdJ_f8dChJWENg7Kpt9m1yqavrdLm7E,1299
|
107
|
+
camomilla/views/mixins/optimize.py,sha256=iRPNkoeIIlJugk7DjJhDPaqeX7Opi7TxnUoMDnxJxUk,686
|
97
108
|
camomilla/views/mixins/ordering.py,sha256=mh7fqPyVCVJh84Nl2pYFQouzGxa-ANF3Wqv0pCb7OVU,4779
|
98
|
-
camomilla/views/mixins/pagination.py,sha256=
|
109
|
+
camomilla/views/mixins/pagination.py,sha256=NWerBdMyBt4Kswig4fbANqGTzsll8SJdE6a8_UIoueU,5772
|
110
|
+
camomilla/views/mixins/permissions.py,sha256=TPmR3Hoa3BjeJu9rCE_7lpLOAupue4WI42C21HTo6X4,200
|
111
|
+
django_camomilla_cms-6.0.0b17.dist-info/licenses/LICENSE,sha256=kVS7zDrNkav2hLLXbOJwVdonY2ToApTK3khyJagGQoQ,1063
|
99
112
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
100
113
|
tests/test_api.py,sha256=t03EFDezGgm4UJl8RIVvnTUkAGTB6ptm0G2lHBQ7ljc,1833
|
101
|
-
tests/test_camomilla_filters.py,sha256=
|
102
|
-
tests/test_media.py,sha256=
|
114
|
+
tests/test_camomilla_filters.py,sha256=5LlR3tctGu6qxVmOrY52AGh_ACvEzdAvkwH2v7medpo,1536
|
115
|
+
tests/test_media.py,sha256=IG-cigWxDnsq54DRVaPO2O0lcsnutfKRsqPTTR8W1E8,4183
|
116
|
+
tests/test_menu.py,sha256=HyEdDzTDsLtNzsTNGjjZ6SCrgTXRU3FkKviUOacnYRg,3582
|
103
117
|
tests/test_model_api.py,sha256=Ne8YlXTH2cqP5gzOc8UKjJuh0t-NaKHh5Ol9krpVHQg,3768
|
104
118
|
tests/test_model_api_permissions.py,sha256=7CSb4-yIOfycAL_vXvh1dE2whx7k0gNkWl9LO0yzy4I,1801
|
119
|
+
tests/test_model_api_register.py,sha256=9pqf7fvtniw63ZD4P2JItfDC0brD55vIrqjZ4phm_qs,14016
|
105
120
|
tests/test_models.py,sha256=WJs8lxWZWn1l7X3a_QFVc8fF5LHTsI8bc3uhQe6-o-Q,684
|
106
|
-
tests/
|
121
|
+
tests/test_pages.py,sha256=qIVdfmbtx7GKHyNWHhirR58gGr9zjfrrzXXkvYlLusc,11469
|
122
|
+
tests/test_query_parser.py,sha256=R9l0L2QDEDcm2b6IFUhyf7wMXLzL9RySLkzKTWRtBkE,2097
|
123
|
+
tests/test_templates_context.py,sha256=D72ufRqCGjInGGXHSNVhlJ1HcWG0zMqrAiTuiaU057k,4694
|
107
124
|
tests/test_utils.py,sha256=o_FG7XOxLePOBfwBr4sk09gej0onWNw9t2-gSjGmgNg,3741
|
108
125
|
tests/fixtures/__init__.py,sha256=NGj22kLV65v56IpOrOVqSkPhJePTXD4QjuuZhZSMwfQ,460
|
109
126
|
tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
110
|
-
tests/utils/api.py,sha256=
|
111
|
-
|
112
|
-
django_camomilla_cms-6.0.
|
113
|
-
django_camomilla_cms-6.0.
|
114
|
-
django_camomilla_cms-6.0.
|
115
|
-
django_camomilla_cms-6.0.
|
127
|
+
tests/utils/api.py,sha256=TYcDXeILHtBwzwG0acwPFmiqMZnlF9VnLB0Ydhg55vA,865
|
128
|
+
tests/utils/media.py,sha256=ChsoHqwWmVYHE7teFsV9swTqBEFD0zcvQSBuKsK9G_s,298
|
129
|
+
django_camomilla_cms-6.0.0b17.dist-info/METADATA,sha256=oiU3jK3ZCjQurWBdq2vaUZgBr2OMim4RLEjSPtIVm28,2565
|
130
|
+
django_camomilla_cms-6.0.0b17.dist-info/WHEEL,sha256=oSJJyWjO7Z2XSScFQUpXG1HL-N0sFMqqeKVVbZTPkWc,109
|
131
|
+
django_camomilla_cms-6.0.0b17.dist-info/top_level.txt,sha256=G9VIGBmMMqC7JEckoTgXKmC6T2BR75QRkqRnngw1_lo,16
|
132
|
+
django_camomilla_cms-6.0.0b17.dist-info/RECORD,,
|
tests/test_camomilla_filters.py
CHANGED
@@ -38,4 +38,4 @@ class CamomillaFiltersTestCase(TestCase):
|
|
38
38
|
request.META["HTTP_HOST"] = "localhost"
|
39
39
|
page = Page.get(request)
|
40
40
|
alt_urls = dict(alternate_urls(page, request))
|
41
|
-
self.assertEqual(alt_urls, {'it': None, 'en': '/path/'})
|
41
|
+
self.assertEqual(alt_urls, {'it': None, 'en': '/path/'})
|