Features: 1) Integrated django-summernote for rich text editing; 2) Added Summernote fields in PostAdmin with configuration; 3) Configured summernote settings in a separated module;
Fixes: 1) Adjusted modeltranslation admin import to use external jQuery variant; 2) Corrected optional flags for package dependencies in poetry.lock; Extra: 1) Removed custom PostAdminForm in favor of SummernoteModelAdmin; 2) Enhanced formatting consistency in api_urls and admin files.
This commit is contained in:
parent
2a7ec836b0
commit
77d978fecb
9 changed files with 74 additions and 37 deletions
|
|
@ -1,30 +1,19 @@
|
|||
from django.contrib import admin
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_summernote.admin import SummernoteModelAdmin
|
||||
|
||||
from .forms import PostAdminForm
|
||||
from .models import Post, PostTag
|
||||
|
||||
|
||||
@admin.register(Post)
|
||||
class PostAdmin(admin.ModelAdmin):
|
||||
def preview_html(self, obj):
|
||||
html = obj.content.html or "<em>{}</em>".format(_("(no content yet)"))
|
||||
# noinspection DjangoSafeString
|
||||
return mark_safe(html)
|
||||
|
||||
preview_html.short_description = _("rendered HTML") # type: ignore
|
||||
|
||||
form = PostAdminForm
|
||||
class PostAdmin(admin.ModelAdmin, SummernoteModelAdmin):
|
||||
list_display = ("title", "author", "slug", "created", "modified")
|
||||
list_filter = ("author", "tags", "created", "modified")
|
||||
search_fields = ("title", "content")
|
||||
filter_horizontal = ("tags",)
|
||||
date_hierarchy = "created"
|
||||
autocomplete_fields = ("author", "tags")
|
||||
summernote_fields = ("content",)
|
||||
|
||||
readonly_fields = ("preview_html",)
|
||||
# noinspection PyUnresolvedReferences
|
||||
fieldsets = (
|
||||
(
|
||||
None,
|
||||
|
|
@ -33,7 +22,6 @@ class PostAdmin(admin.ModelAdmin):
|
|||
"author",
|
||||
"title",
|
||||
"content",
|
||||
"preview_html",
|
||||
"file",
|
||||
"tags",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
from django import forms
|
||||
|
||||
from blog.models import Post
|
||||
from blog.widgets import MarkdownEditorWidget
|
||||
|
||||
|
||||
class PostAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = ("author", "content", "tags", "title")
|
||||
widgets = {
|
||||
"content": MarkdownEditorWidget(attrs={"style": "min-height: 500px;"}),
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ from django.contrib.admin import ModelAdmin, TabularInline
|
|||
from django.contrib.gis.admin import GISModelAdmin
|
||||
from django.urls import path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from modeltranslation.admin import TabbedTranslationAdmin
|
||||
from modeltranslation.admin import (
|
||||
TabbedExternalJqueryTranslationAdmin as TabbedTranslationAdmin,
|
||||
)
|
||||
from mptt.admin import DraggableMPTTAdmin
|
||||
|
||||
from evibes.settings import CONSTANCE_CONFIG
|
||||
|
|
|
|||
|
|
@ -7,20 +7,40 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from drf_spectacular.views import SpectacularAPIView
|
||||
|
||||
from core.graphene.schema import schema
|
||||
from core.views import CustomGraphQLView, CustomRedocView, CustomSwaggerView, favicon_view, index
|
||||
from core.views import (
|
||||
CustomGraphQLView,
|
||||
CustomRedocView,
|
||||
CustomSwaggerView,
|
||||
favicon_view,
|
||||
index,
|
||||
)
|
||||
from evibes.settings import SPECTACULAR_PLATFORM_SETTINGS
|
||||
|
||||
urlpatterns = [
|
||||
path(r"health/", include("health_check.urls")),
|
||||
path("prometheus/", include("django_prometheus.urls")),
|
||||
path(r"graphql/", csrf_exempt(CustomGraphQLView.as_view(graphiql=True, schema=schema))),
|
||||
path(
|
||||
r"graphql/",
|
||||
csrf_exempt(CustomGraphQLView.as_view(graphiql=True, schema=schema)),
|
||||
),
|
||||
path(
|
||||
r"docs/",
|
||||
SpectacularAPIView.as_view(urlconf="evibes.api_urls", custom_settings=SPECTACULAR_PLATFORM_SETTINGS),
|
||||
SpectacularAPIView.as_view(
|
||||
urlconf="evibes.api_urls", custom_settings=SPECTACULAR_PLATFORM_SETTINGS
|
||||
),
|
||||
name="schema-platform",
|
||||
),
|
||||
path(r"docs/swagger/", CustomSwaggerView.as_view(url_name="schema-platform"), name="swagger-ui-platform"),
|
||||
path(r"docs/redoc/", CustomRedocView.as_view(url_name="schema-platform"), name="redoc-ui-platform"),
|
||||
path(
|
||||
r"docs/swagger/",
|
||||
CustomSwaggerView.as_view(url_name="schema-platform"),
|
||||
name="swagger-ui-platform",
|
||||
),
|
||||
path(
|
||||
r"docs/redoc/",
|
||||
CustomRedocView.as_view(url_name="schema-platform"),
|
||||
name="redoc-ui-platform",
|
||||
),
|
||||
path("summernote/", include("django_summernote.urls")),
|
||||
path(r"i18n/", include("django.conf.urls.i18n")),
|
||||
path(r"favicon.ico", favicon_view),
|
||||
path(r"", index),
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@ from .emailing import * # noqa: F403
|
|||
from .extensions import * # noqa: F403
|
||||
from .graphene import * # noqa: F403
|
||||
from .logconfig import * # noqa: F403
|
||||
from .summernote import * # noqa: F403
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ INSTALLED_APPS: list[str] = [
|
|||
"django_celery_results",
|
||||
"django_extensions",
|
||||
"django_redis",
|
||||
"django_summernote",
|
||||
"widget_tweaks",
|
||||
"mptt",
|
||||
"rest_framework",
|
||||
|
|
|
|||
20
evibes/settings/summernote.py
Normal file
20
evibes/settings/summernote.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
SUMMERNOTE_THEME = "bs5"
|
||||
SUMMERNOTE_CONFIG = {
|
||||
"iframe": False,
|
||||
"summernote": {
|
||||
"lang": None,
|
||||
"toolbar": [
|
||||
["style", ["style"]],
|
||||
["font", ["bold", "underline", "clear"]],
|
||||
["fontname", ["fontname"]],
|
||||
["color", ["color"]],
|
||||
["para", ["ul", "ol", "paragraph"]],
|
||||
["table", ["table"]],
|
||||
["insert", ["link", "picture", "video"]],
|
||||
["view", ["fullscreen", "codeview", "help"]],
|
||||
],
|
||||
},
|
||||
"attachment_require_authentication": True,
|
||||
"disable_attachment": False,
|
||||
"attachment_absolute_uri": True,
|
||||
}
|
||||
23
poetry.lock
generated
23
poetry.lock
generated
|
|
@ -395,7 +395,7 @@ uvloop = ["uvloop (>=0.15.2)"]
|
|||
name = "bleach"
|
||||
version = "6.2.0"
|
||||
description = "An easy safelist-based HTML-sanitizing tool."
|
||||
optional = true
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e"},
|
||||
|
|
@ -1477,6 +1477,23 @@ files = [
|
|||
django = "*"
|
||||
typing-extensions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "django-summernote"
|
||||
version = "0.8.20.0"
|
||||
description = "Summernote plugin for Django"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "django-summernote-0.8.20.0.tar.gz", hash = "sha256:52e9b12438ed9eac0d77729f758f2aae06e468b5cbce133e24100d58ae4e43a8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
bleach = "*"
|
||||
django = "*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["django-dummy-plug", "pytest", "pytest-django"]
|
||||
|
||||
[[package]]
|
||||
name = "django-timezone-field"
|
||||
version = "7.1"
|
||||
|
|
@ -4955,7 +4972,7 @@ files = [
|
|||
name = "webencodings"
|
||||
version = "0.5.1"
|
||||
description = "Character encoding aliases for legacy web content"
|
||||
optional = true
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
|
||||
|
|
@ -5135,4 +5152,4 @@ worker = ["celery", "celery-prometheus-exporter", "django-celery-beat", "django-
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.12,<3.13"
|
||||
content-hash = "f0d3ee182729fb4060ac11cd915a5c548203ab3ab4ab0b56e5a97947b3056e43"
|
||||
content-hash = "db1001cbb7cbb20f5a927eb20c69e706bf6620cdc60e8334bede11439ce12c21"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ django-redis = "6.0.0"
|
|||
django-ratelimit = "4.1.0"
|
||||
django-storages = "1.14.6"
|
||||
django-stubs = "5.2.1"
|
||||
django-summernote = "0.8.20.0"
|
||||
django-widget-tweaks = "1.5.0"
|
||||
django-md-field = "0.1.0"
|
||||
djangorestframework = "3.16.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue