django-camomilla-cms 6.0.0b12__py2.py3-none-any.whl → 6.0.0b13__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/managers/__init__.py +3 -0
- camomilla/managers/pages.py +31 -0
- camomilla/models/page.py +31 -3
- camomilla/theme/__init__.py +1 -1
- {django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/METADATA +1 -1
- {django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/RECORD +10 -8
- {django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/WHEEL +1 -1
- {django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/LICENSE +0 -0
- {django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/top_level.txt +0 -0
camomilla/__init__.py
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
from typing import Any, Tuple
|
2
|
+
from django.db.models.query import QuerySet
|
3
|
+
from django.db import transaction
|
4
|
+
from django.apps import apps
|
5
|
+
|
6
|
+
URL_NODE_RELATED_NAME = "%(app_label)s_%(class)s"
|
7
|
+
|
8
|
+
|
9
|
+
class PageQuerySet(QuerySet):
|
10
|
+
def get_or_create(self, defaults=None, **kwargs) -> Tuple[Any, bool]:
|
11
|
+
if "permalink" in kwargs:
|
12
|
+
with transaction.atomic():
|
13
|
+
UrlNode = apps.get_model("camomilla", "UrlNode")
|
14
|
+
url_node, created = UrlNode.objects.get_or_create(
|
15
|
+
permalink=kwargs.pop("permalink"),
|
16
|
+
related_name=URL_NODE_RELATED_NAME % self.model_info
|
17
|
+
)
|
18
|
+
if created is False and url_node.page is not None:
|
19
|
+
page = self.get(**kwargs)
|
20
|
+
if page.pk != url_node.page.pk:
|
21
|
+
raise self.model.MultipleObjectsReturned(
|
22
|
+
"got more than one %s object for the same permalink: %s"
|
23
|
+
% (
|
24
|
+
self.model._meta.object_name,
|
25
|
+
kwargs["permalink"],
|
26
|
+
)
|
27
|
+
)
|
28
|
+
return url_node.page, False
|
29
|
+
kwargs["url_node"] = url_node
|
30
|
+
return super().get_or_create(defaults, **kwargs)
|
31
|
+
return super().get_or_create(defaults, **kwargs)
|
camomilla/models/page.py
CHANGED
@@ -2,6 +2,8 @@ from typing import Sequence, Tuple
|
|
2
2
|
from uuid import uuid4
|
3
3
|
|
4
4
|
from django.core.exceptions import ObjectDoesNotExist
|
5
|
+
from django.core.validators import RegexValidator
|
6
|
+
|
5
7
|
from django.db import ProgrammingError, OperationalError, models, transaction
|
6
8
|
from django.db.models.signals import post_delete
|
7
9
|
from django.dispatch import receiver
|
@@ -12,6 +14,7 @@ from django.utils.functional import lazy
|
|
12
14
|
from django.utils.text import slugify
|
13
15
|
from django.utils.translation import gettext_lazy as _
|
14
16
|
|
17
|
+
from camomilla.managers.pages import PageQuerySet
|
15
18
|
from camomilla.models.mixins import MetaMixin, SeoMixin
|
16
19
|
from camomilla.utils import (
|
17
20
|
activate_languages,
|
@@ -164,6 +167,16 @@ class PageBase(models.base.ModelBase):
|
|
164
167
|
return new_class
|
165
168
|
|
166
169
|
|
170
|
+
class UrlPathValidator(RegexValidator):
|
171
|
+
|
172
|
+
regex = r"^[a-zA-Z0-9_\-\/]+[^\/]$"
|
173
|
+
message = _(
|
174
|
+
"Enter a valid 'slug' consisting of lowercase letters, numbers, "
|
175
|
+
"underscores, hyphens and slashes."
|
176
|
+
)
|
177
|
+
flags = 0
|
178
|
+
|
179
|
+
|
167
180
|
class AbstractPage(SeoMixin, MetaMixin, models.Model, metaclass=PageBase):
|
168
181
|
date_created = models.DateTimeField(auto_now_add=True)
|
169
182
|
date_updated_at = models.DateTimeField(auto_now=True)
|
@@ -175,7 +188,9 @@ class AbstractPage(SeoMixin, MetaMixin, models.Model, metaclass=PageBase):
|
|
175
188
|
editable=False,
|
176
189
|
)
|
177
190
|
breadcrumbs_title = models.CharField(max_length=128, null=True, blank=True)
|
178
|
-
slug = models.
|
191
|
+
slug = models.CharField(
|
192
|
+
max_length=150, null=True, blank=True, validators=[UrlPathValidator()]
|
193
|
+
)
|
179
194
|
status = models.CharField(
|
180
195
|
max_length=3,
|
181
196
|
choices=PAGE_STATUS,
|
@@ -195,6 +210,8 @@ class AbstractPage(SeoMixin, MetaMixin, models.Model, metaclass=PageBase):
|
|
195
210
|
on_delete=models.CASCADE,
|
196
211
|
)
|
197
212
|
|
213
|
+
objects = PageQuerySet.as_manager()
|
214
|
+
|
198
215
|
def __init__(self, *args, **kwargs):
|
199
216
|
super(AbstractPage, self).__init__(*args, **kwargs)
|
200
217
|
self._meta.get_field("template").choices = lazy(GET_TEMPLATE_CHOICES, list)()
|
@@ -294,7 +311,10 @@ class AbstractPage(SeoMixin, MetaMixin, models.Model, metaclass=PageBase):
|
|
294
311
|
else fallback_slug
|
295
312
|
)
|
296
313
|
set_nofallbacks(self, "slug", slug)
|
297
|
-
|
314
|
+
slug_parts = (slug or "").split("/")
|
315
|
+
for i, part in enumerate(slug_parts):
|
316
|
+
slug_parts[i] = slugify(part, allow_unicode=True)
|
317
|
+
permalink = "/%s" % "/".join(slug_parts)
|
298
318
|
if self.parent:
|
299
319
|
permalink = f"{self.parent.permalink}{permalink}"
|
300
320
|
qs = UrlNode.objects.exclude(pk=getattr(self.url_node or object, "pk", None))
|
@@ -376,12 +396,20 @@ class AbstractPage(SeoMixin, MetaMixin, models.Model, metaclass=PageBase):
|
|
376
396
|
raise Http404(ex)
|
377
397
|
|
378
398
|
def alternate_urls(self, *args, **kwargs) -> dict:
|
399
|
+
request = False
|
400
|
+
if len(args) > 0:
|
401
|
+
request = args[0]
|
402
|
+
if "request" in kwargs:
|
403
|
+
request = kwargs["request"]
|
404
|
+
preview = request and getattr(request, "GET", {}).get("preview", False)
|
379
405
|
permalinks = get_field_translations(self.url_node or object, "permalink", None)
|
380
406
|
for lang in activate_languages():
|
381
407
|
if lang in permalinks:
|
382
408
|
permalinks[lang] = (
|
383
|
-
UrlNode.reverse_url(permalinks[lang]) if self.is_public else None
|
409
|
+
UrlNode.reverse_url(permalinks[lang]) if preview or self.is_public else None
|
384
410
|
)
|
411
|
+
if preview:
|
412
|
+
permalinks = {k: f"{v}?preview=true" for k, v in permalinks.items()}
|
385
413
|
return permalinks
|
386
414
|
|
387
415
|
class Meta:
|
camomilla/theme/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "6.0.0-beta.
|
1
|
+
__version__ = "6.0.0-beta.13"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
camomilla/__init__.py,sha256=
|
1
|
+
camomilla/__init__.py,sha256=90D5d1Eo-RHeFug2xM5JHCF6vTFsJbCV_XYQqUIMlpc,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
|
@@ -22,12 +22,14 @@ camomilla/fields/json.py,sha256=tWEDn6kwTP6pNB53djxuVPu2d57m9cIDc4ccCEfUbDQ,1938
|
|
22
22
|
camomilla/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
camomilla/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
camomilla/management/commands/regenerate_thumbnails.py,sha256=pKToASR8p8TJezGpFfuylsAHtriNueJ7xqJJxq55adY,496
|
25
|
+
camomilla/managers/__init__.py,sha256=Zwp28E1RKafIl0FqcUi1YNHxF19IsMIvhlhS-Njg9Mw,60
|
26
|
+
camomilla/managers/pages.py,sha256=FVXEW1G-O32kUJO4wejYi8QuDp1DIF5FOyj1rSewS0k,1380
|
25
27
|
camomilla/models/__init__.py,sha256=y7Q34AGhQ1weJUKWb6XjiyUbwRnJeylOBGMErU0wqYg,147
|
26
28
|
camomilla/models/article.py,sha256=LgkZgRsubtDV6NwBz8E2bIgKD6H3I-1QLAxEan5TYYs,1139
|
27
29
|
camomilla/models/content.py,sha256=mIgtifb_WMIt58we5u6qWZemHvuDN1zZaBeCyzHL78A,956
|
28
30
|
camomilla/models/media.py,sha256=7TD_0nhNoi8P-Gmsr0Kag4eGaxMXuTfQOFl53Mb03cQ,6854
|
29
31
|
camomilla/models/menu.py,sha256=rCq0MfHLGM7-7fDVk--AixQZb6_C1gkWMWffKs6QnK4,2841
|
30
|
-
camomilla/models/page.py,sha256=
|
32
|
+
camomilla/models/page.py,sha256=X4Mo4cTbAYyWlpVFtjRjyvI_wE2-zcBU1MR8mm26NQI,15671
|
31
33
|
camomilla/models/mixins/__init__.py,sha256=c2NixqvrIX4E9WGRqQbylXlqBWDXEqN9mzs_dpB0hFQ,1248
|
32
34
|
camomilla/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
35
|
camomilla/openapi/schema.py,sha256=kYNtIKnLx4SIj893umIE6u-q3HH9hYH9O4zdZCSOe7U,2100
|
@@ -67,7 +69,7 @@ camomilla/templates_context/rendering.py,sha256=GfTR45_gC7WT7zTKPVXkBDwe22uF63A-
|
|
67
69
|
camomilla/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
70
|
camomilla/templatetags/camomilla_filters.py,sha256=35x0-cWrRHeLhqypSLlJzEFY_fQDcRHiwZQpFgIsspE,692
|
69
71
|
camomilla/templatetags/menus.py,sha256=pLFeJ1UAm3flsU9TNo2iQk4otSwZuJPr86Nf408dZ-8,862
|
70
|
-
camomilla/theme/__init__.py,sha256=
|
72
|
+
camomilla/theme/__init__.py,sha256=mU1IlOIVAJC-fMxsbdHtQSVGPT8J6cMmDZXINJZJvBc,30
|
71
73
|
camomilla/theme/admin.py,sha256=R3QAfqaF9mhzwfyb_m2_hqTQ2hBcNvQts1MWUX4dUUM,2462
|
72
74
|
camomilla/theme/apps.py,sha256=ecqG8ntWdOighYOEHQOMVQpa5g_1WEzzpaaGjnOi9uA,1195
|
73
75
|
camomilla/theme/static/admin/css/responsive.css,sha256=yGq6qXrr8xEVsXTnprIBgkX-sMGZrNf0Kkh-xDxf6yE,157
|
@@ -100,8 +102,8 @@ tests/test_api.py,sha256=DTXtvNNRwvZvxGKi6LyCzhpyU1OzPWGSbBUfRL3-Nck,2101
|
|
100
102
|
tests/test_camomilla_filters.py,sha256=_W9CcwsEyewMBvnNYKk4CVqrkXxRYejle3mjiBS7hqk,1848
|
101
103
|
tests/test_models.py,sha256=WJs8lxWZWn1l7X3a_QFVc8fF5LHTsI8bc3uhQe6-o-Q,684
|
102
104
|
tests/test_utils.py,sha256=0tdEDBaBkyjAXpbqP0SpFcfgO56MV2TWZmk9xpjR7J0,3613
|
103
|
-
django_camomilla_cms-6.0.
|
104
|
-
django_camomilla_cms-6.0.
|
105
|
-
django_camomilla_cms-6.0.
|
106
|
-
django_camomilla_cms-6.0.
|
107
|
-
django_camomilla_cms-6.0.
|
105
|
+
django_camomilla_cms-6.0.0b13.dist-info/LICENSE,sha256=kVS7zDrNkav2hLLXbOJwVdonY2ToApTK3khyJagGQoQ,1063
|
106
|
+
django_camomilla_cms-6.0.0b13.dist-info/METADATA,sha256=axotQ6_8ytKQdCOmKjySs29ExAKuIF8KHcnTqZLoZEM,2410
|
107
|
+
django_camomilla_cms-6.0.0b13.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
108
|
+
django_camomilla_cms-6.0.0b13.dist-info/top_level.txt,sha256=G9VIGBmMMqC7JEckoTgXKmC6T2BR75QRkqRnngw1_lo,16
|
109
|
+
django_camomilla_cms-6.0.0b13.dist-info/RECORD,,
|
File without changes
|
{django_camomilla_cms-6.0.0b12.dist-info → django_camomilla_cms-6.0.0b13.dist-info}/top_level.txt
RENAMED
File without changes
|