django-camomilla-cms 5.8.5__py2.py3-none-any.whl → 6.0.0__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 +8 -2
- camomilla/apps.py +9 -1
- camomilla/context_processors.py +6 -0
- camomilla/contrib/modeltranslation/__init__.py +0 -0
- camomilla/contrib/modeltranslation/hvad_migration.py +126 -0
- camomilla/dynamic_pages_urls.py +33 -0
- camomilla/fields/__init__.py +13 -0
- camomilla/{fields.py → fields/json.py} +15 -18
- camomilla/management/commands/regenerate_thumbnails.py +0 -1
- camomilla/managers/__init__.py +3 -0
- camomilla/managers/pages.py +116 -0
- camomilla/model_api.py +86 -0
- camomilla/models/__init__.py +5 -6
- camomilla/models/article.py +26 -44
- camomilla/models/content.py +8 -15
- camomilla/models/media.py +70 -97
- camomilla/models/menu.py +106 -0
- camomilla/models/mixins/__init__.py +10 -48
- camomilla/models/page.py +521 -20
- camomilla/openapi/__init__.py +0 -0
- camomilla/openapi/schema.py +67 -0
- camomilla/parsers.py +0 -1
- camomilla/redirects.py +10 -0
- camomilla/serializers/__init__.py +2 -0
- camomilla/serializers/article.py +5 -10
- camomilla/serializers/base/__init__.py +21 -17
- camomilla/serializers/content_type.py +17 -0
- camomilla/serializers/fields/__init__.py +6 -20
- camomilla/serializers/fields/file.py +5 -0
- camomilla/serializers/fields/related.py +24 -4
- camomilla/serializers/media.py +6 -8
- camomilla/serializers/menu.py +17 -0
- camomilla/serializers/mixins/__init__.py +23 -187
- camomilla/serializers/mixins/fields.py +20 -0
- camomilla/serializers/mixins/filter_fields.py +57 -0
- 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/serializers/mixins/translation.py +103 -0
- camomilla/serializers/page.py +53 -4
- camomilla/serializers/user.py +5 -4
- camomilla/serializers/utils.py +38 -0
- camomilla/serializers/validators.py +51 -0
- camomilla/settings.py +118 -0
- camomilla/sitemap.py +30 -0
- camomilla/storages/__init__.py +4 -0
- camomilla/storages/default.py +12 -0
- camomilla/storages/optimize.py +71 -0
- camomilla/{storages.py → storages/overwrite.py} +2 -2
- camomilla/templates/admin/camomilla/page/change_form.html +10 -0
- camomilla/templates/defaults/articles/default.html +7 -0
- camomilla/templates/defaults/base.html +170 -0
- camomilla/templates/defaults/pages/default.html +3 -0
- camomilla/templates/defaults/parts/langswitch.html +83 -0
- camomilla/templates/defaults/parts/menu.html +15 -0
- camomilla/templates_context/__init__.py +0 -0
- camomilla/templates_context/autodiscover.py +51 -0
- camomilla/templates_context/rendering.py +89 -0
- camomilla/templatetags/camomilla_filters.py +6 -5
- camomilla/templatetags/menus.py +37 -0
- camomilla/templatetags/model_extras.py +77 -0
- camomilla/theme/__init__.py +1 -1
- camomilla/theme/admin/__init__.py +99 -0
- camomilla/theme/admin/pages.py +46 -0
- camomilla/theme/admin/translations.py +13 -0
- camomilla/theme/apps.py +38 -0
- camomilla/theme/static/admin/css/responsive.css +5 -1021
- camomilla/theme/static/admin/img/favicon.ico +0 -0
- camomilla/theme/static/admin/img/logo.svg +31 -0
- camomilla/theme/templates/admin/base.html +7 -0
- camomilla/theme/templates/rosetta/base.html +196 -0
- camomilla/translation.py +61 -0
- camomilla/urls.py +38 -17
- camomilla/utils/__init__.py +4 -0
- camomilla/utils/getters.py +27 -0
- camomilla/utils/normalization.py +7 -0
- camomilla/utils/query_parser.py +167 -0
- camomilla/{utils.py → utils/seo.py} +13 -15
- camomilla/utils/setters.py +37 -0
- camomilla/utils/templates.py +32 -0
- camomilla/utils/translation.py +114 -0
- camomilla/views/__init__.py +1 -1
- camomilla/views/articles.py +5 -7
- camomilla/views/base/__init__.py +35 -5
- camomilla/views/contents.py +6 -11
- camomilla/views/decorators.py +26 -0
- camomilla/views/medias.py +24 -19
- camomilla/views/menus.py +81 -0
- camomilla/views/mixins/__init__.py +17 -73
- 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/ordering.py +2 -2
- camomilla/views/mixins/pagination.py +12 -18
- camomilla/views/mixins/permissions.py +6 -0
- camomilla/views/pages.py +28 -6
- camomilla/views/tags.py +5 -6
- camomilla/views/users.py +7 -12
- django_camomilla_cms-6.0.0.dist-info/METADATA +123 -0
- django_camomilla_cms-6.0.0.dist-info/RECORD +133 -0
- {django_camomilla_cms-5.8.5.dist-info → django_camomilla_cms-6.0.0.dist-info}/WHEEL +1 -1
- tests/fixtures/__init__.py +14 -0
- tests/test_api.py +22 -39
- tests/test_camomilla_filters.py +11 -13
- tests/test_media.py +152 -0
- tests/test_menu.py +112 -0
- tests/test_model_api.py +113 -0
- tests/test_model_api_permissions.py +44 -0
- tests/test_model_api_register.py +355 -0
- tests/test_pages.py +351 -0
- tests/test_query_parser.py +58 -0
- tests/test_templates_context.py +149 -0
- tests/test_utils.py +64 -64
- tests/utils/__init__.py +0 -0
- tests/utils/api.py +28 -0
- tests/utils/media.py +10 -0
- camomilla/admin.py +0 -98
- camomilla/migrations/0001_initial.py +0 -577
- camomilla/migrations/0002_auto_20200214_1127.py +0 -33
- camomilla/migrations/0003_auto_20210130_1610.py +0 -30
- camomilla/migrations/0004_auto_20210511_0937.py +0 -25
- camomilla/migrations/0005_media_image_props.py +0 -19
- camomilla/migrations/0006_auto_20220103_1845.py +0 -35
- camomilla/migrations/0007_auto_20220211_1622.py +0 -18
- camomilla/migrations/0008_auto_20220309_1616.py +0 -60
- camomilla/migrations/0009_article__hvad_query_category__hvad_query_and_more.py +0 -165
- camomilla/migrations/0010_auto_20220802_1406.py +0 -83
- camomilla/migrations/0011_auto_20220902_1000.py +0 -15
- camomilla/models/category.py +0 -25
- camomilla/models/tag.py +0 -19
- camomilla/theme/static/admin/img/logo.png +0 -0
- camomilla/theme/templates/admin/base_site.html +0 -18
- camomilla/views/categories.py +0 -13
- django_camomilla_cms-5.8.5.dist-info/METADATA +0 -62
- django_camomilla_cms-5.8.5.dist-info/RECORD +0 -76
- tests/urls.py +0 -21
- /camomilla/{migrations → contrib}/__init__.py +0 -0
- /camomilla/templates/{camomilla → defaults}/widgets/media_select_multiple.html +0 -0
- {django_camomilla_cms-5.8.5.dist-info → django_camomilla_cms-6.0.0.dist-info/licenses}/LICENSE +0 -0
- {django_camomilla_cms-5.8.5.dist-info → django_camomilla_cms-6.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
from tinymce.widgets import TinyMCE
|
2
|
+
from django import forms
|
3
|
+
from django.contrib import admin
|
4
|
+
from django.http import HttpResponse
|
5
|
+
from .pages import AbstractPageModelForm, AbstractPageAdmin
|
6
|
+
from .translations import TranslationAwareModelAdmin
|
7
|
+
from camomilla.models import (
|
8
|
+
Article,
|
9
|
+
Content,
|
10
|
+
Media,
|
11
|
+
MediaFolder,
|
12
|
+
Page,
|
13
|
+
Tag,
|
14
|
+
Menu,
|
15
|
+
UrlRedirect,
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
class UserProfileAdmin(admin.ModelAdmin):
|
20
|
+
pass
|
21
|
+
|
22
|
+
|
23
|
+
class ArticleAdminForm(AbstractPageModelForm):
|
24
|
+
class Meta:
|
25
|
+
model = Article
|
26
|
+
fields = "__all__"
|
27
|
+
widgets = {"content": TinyMCE()}
|
28
|
+
|
29
|
+
|
30
|
+
class ArticleAdmin(AbstractPageAdmin):
|
31
|
+
filter_horizontal = ("tags",)
|
32
|
+
form = ArticleAdminForm
|
33
|
+
|
34
|
+
|
35
|
+
class TagAdmin(TranslationAwareModelAdmin):
|
36
|
+
pass
|
37
|
+
|
38
|
+
|
39
|
+
class MediaFolderAdmin(admin.ModelAdmin):
|
40
|
+
readonly_fields = ("path",)
|
41
|
+
|
42
|
+
|
43
|
+
class ContentAdminForm(forms.ModelForm):
|
44
|
+
class Meta:
|
45
|
+
model = Content
|
46
|
+
fields = "__all__"
|
47
|
+
widgets = {"content": TinyMCE()}
|
48
|
+
|
49
|
+
|
50
|
+
class ContentAdmin(TranslationAwareModelAdmin):
|
51
|
+
form = ContentAdminForm
|
52
|
+
|
53
|
+
|
54
|
+
class MediaAdmin(TranslationAwareModelAdmin):
|
55
|
+
exclude = (
|
56
|
+
"thumbnail",
|
57
|
+
"size",
|
58
|
+
"image_props",
|
59
|
+
)
|
60
|
+
readonly_fields = ("image_preview", "image_thumb_preview", "mime_type")
|
61
|
+
list_display = (
|
62
|
+
"__str__",
|
63
|
+
"title",
|
64
|
+
"image_thumb_preview",
|
65
|
+
)
|
66
|
+
|
67
|
+
def response_add(self, request, obj):
|
68
|
+
if request.GET.get("_popup", ""):
|
69
|
+
return HttpResponse(
|
70
|
+
"""
|
71
|
+
<script type="text/javascript">
|
72
|
+
opener.dismissAddRelatedObjectPopup(window, %s, '%s');
|
73
|
+
</script>"""
|
74
|
+
% (obj.id, obj.json_repr)
|
75
|
+
)
|
76
|
+
else:
|
77
|
+
return super(MediaAdmin, self).response_add(request, obj)
|
78
|
+
|
79
|
+
|
80
|
+
class PageAdmin(AbstractPageAdmin):
|
81
|
+
pass
|
82
|
+
|
83
|
+
|
84
|
+
class MenuAdmin(TranslationAwareModelAdmin):
|
85
|
+
pass
|
86
|
+
|
87
|
+
|
88
|
+
class UrlRedirectAdmin(admin.ModelAdmin):
|
89
|
+
pass
|
90
|
+
|
91
|
+
|
92
|
+
admin.site.register(Article, ArticleAdmin)
|
93
|
+
admin.site.register(MediaFolder, MediaFolderAdmin)
|
94
|
+
admin.site.register(Tag, TagAdmin)
|
95
|
+
admin.site.register(Content, ContentAdmin)
|
96
|
+
admin.site.register(Media, MediaAdmin)
|
97
|
+
admin.site.register(Page, PageAdmin)
|
98
|
+
admin.site.register(Menu, MenuAdmin)
|
99
|
+
admin.site.register(UrlRedirect, UrlRedirectAdmin)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
from django import forms
|
2
|
+
from camomilla import settings
|
3
|
+
from .translations import TranslationAwareModelAdmin
|
4
|
+
from camomilla.models import UrlNode
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractPageModelFormMeta(forms.models.ModelFormMetaclass):
|
8
|
+
def __new__(mcs, name, bases, attrs):
|
9
|
+
new_class = super().__new__(mcs, name, bases, attrs)
|
10
|
+
fields_to_add = forms.fields_for_model(UrlNode, UrlNode.LANG_PERMALINK_FIELDS)
|
11
|
+
if settings.ENABLE_TRANSLATIONS:
|
12
|
+
for i, field_name in enumerate(fields_to_add.keys()):
|
13
|
+
field_classes = ["mt", f"mt-field-{field_name.replace('_', '-')}"]
|
14
|
+
i == 0 and field_classes.append("mt-default")
|
15
|
+
fields_to_add[field_name].widget.attrs.update(
|
16
|
+
{"class": " ".join(field_classes)}
|
17
|
+
)
|
18
|
+
new_class.base_fields.update(fields_to_add)
|
19
|
+
return new_class
|
20
|
+
|
21
|
+
|
22
|
+
class AbstractPageModelForm(
|
23
|
+
forms.models.BaseModelForm, metaclass=AbstractPageModelFormMeta
|
24
|
+
):
|
25
|
+
|
26
|
+
def get_initial_for_field(self, field, field_name):
|
27
|
+
if field_name in UrlNode.LANG_PERMALINK_FIELDS:
|
28
|
+
return getattr(self.instance, field_name)
|
29
|
+
return super().get_initial_for_field(field, field_name)
|
30
|
+
|
31
|
+
def save(self, commit: bool = True):
|
32
|
+
model = super().save(commit=False)
|
33
|
+
for field_name in UrlNode.LANG_PERMALINK_FIELDS:
|
34
|
+
if field_name in self.cleaned_data:
|
35
|
+
if getattr(model, field_name) != self.cleaned_data[field_name]:
|
36
|
+
# sets autopermalink to False if permalink is manually set
|
37
|
+
setattr(model, f"auto{field_name}", False)
|
38
|
+
setattr(model, field_name, self.cleaned_data[field_name])
|
39
|
+
if commit:
|
40
|
+
model.save()
|
41
|
+
return model
|
42
|
+
|
43
|
+
|
44
|
+
class AbstractPageAdmin(TranslationAwareModelAdmin):
|
45
|
+
form = AbstractPageModelForm
|
46
|
+
change_form_template = "admin/camomilla/page/change_form.html"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from camomilla import settings
|
2
|
+
|
3
|
+
if settings.ENABLE_TRANSLATIONS:
|
4
|
+
from modeltranslation.admin import (
|
5
|
+
TabbedTranslationAdmin as TranslationAwareModelAdmin,
|
6
|
+
)
|
7
|
+
else:
|
8
|
+
from django.contrib.admin import ModelAdmin as TranslationAwareModelAdmin
|
9
|
+
|
10
|
+
|
11
|
+
__all__ = [
|
12
|
+
"TranslationAwareModelAdmin",
|
13
|
+
]
|
camomilla/theme/apps.py
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
from __future__ import unicode_literals
|
2
|
+
from collections import OrderedDict
|
3
|
+
|
4
|
+
from django.apps import AppConfig, apps
|
5
|
+
from django.conf import settings
|
6
|
+
|
7
|
+
|
8
|
+
def add_apps(*app_list):
|
9
|
+
installed_apps = getattr(settings, "INSTALLED_APPS", [])
|
10
|
+
changed = False
|
11
|
+
for app in app_list:
|
12
|
+
if app not in installed_apps:
|
13
|
+
changed = True
|
14
|
+
installed_apps = [app, *installed_apps]
|
15
|
+
if changed:
|
16
|
+
setattr(settings, "INSTALLED_APPS", installed_apps)
|
17
|
+
apps.app_configs = OrderedDict()
|
18
|
+
apps.apps_ready = apps.models_ready = apps.loading = apps.ready = False
|
19
|
+
apps.clear_cache()
|
20
|
+
apps.populate(settings.INSTALLED_APPS)
|
21
|
+
|
22
|
+
|
23
|
+
def set_default_settings(**kwargs):
|
24
|
+
for key, value in kwargs.items():
|
25
|
+
setattr(settings, key, getattr(settings, key, value))
|
26
|
+
|
27
|
+
|
28
|
+
class CamomillaThemeConfig(AppConfig):
|
29
|
+
name = "camomilla.theme"
|
30
|
+
|
31
|
+
def ready(self):
|
32
|
+
add_apps(
|
33
|
+
"tinymce",
|
34
|
+
"django_jsonform",
|
35
|
+
"admin_interface",
|
36
|
+
"colorfield",
|
37
|
+
"structured",
|
38
|
+
)
|