mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 05:07:50 +02:00
Replace ckeditor with tinymce (#30)
* Replace ckeditor with tinymce due to deprecation * Remove any ckeditor dependency from old migrations Disable alters, replace create with plain models.TextField * Reformat files * Add more hardening in image_upload
This commit is contained in:
Submodule arduino/CommandStation-EX updated: 2db2b0ecc6...3b162996ad
@@ -1,6 +1,7 @@
|
|||||||
# Generated by Django 4.2.5 on 2023-10-01 20:16
|
# Generated by Django 4.2.5 on 2023-10-01 20:16
|
||||||
|
|
||||||
import ckeditor_uploader.fields
|
# ckeditor removal
|
||||||
|
# import ckeditor_uploader.fields
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import uuid
|
import uuid
|
||||||
@@ -47,7 +48,8 @@ class Migration(migrations.Migration):
|
|||||||
("ISBN", models.CharField(max_length=13, unique=True)),
|
("ISBN", models.CharField(max_length=13, unique=True)),
|
||||||
("publication_year", models.SmallIntegerField(blank=True, null=True)),
|
("publication_year", models.SmallIntegerField(blank=True, null=True)),
|
||||||
("purchase_date", models.DateField(blank=True, null=True)),
|
("purchase_date", models.DateField(blank=True, null=True)),
|
||||||
("notes", ckeditor_uploader.fields.RichTextUploadingField(blank=True)),
|
# ("notes", ckeditor_uploader.fields.RichTextUploadingField(blank=True)),
|
||||||
|
("notes", models.TextField(blank=True)),
|
||||||
("creation_time", models.DateTimeField(auto_now_add=True)),
|
("creation_time", models.DateTimeField(auto_now_add=True)),
|
||||||
("updated_time", models.DateTimeField(auto_now=True)),
|
("updated_time", models.DateTimeField(auto_now=True)),
|
||||||
("authors", models.ManyToManyField(to="bookshelf.author")),
|
("authors", models.ManyToManyField(to="bookshelf.author")),
|
||||||
|
19
ram/bookshelf/migrations/0012_alter_book_notes.py
Normal file
19
ram/bookshelf/migrations/0012_alter_book_notes.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("bookshelf", "0011_alter_book_language"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="book",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -6,7 +6,7 @@ from django.conf import settings
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_countries.fields import CountryField
|
from django_countries.fields import CountryField
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from metadata.models import Tag
|
from metadata.models import Tag
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
@@ -56,7 +56,7 @@ class Book(models.Model):
|
|||||||
tags = models.ManyToManyField(
|
tags = models.ManyToManyField(
|
||||||
Tag, related_name="bookshelf", blank=True
|
Tag, related_name="bookshelf", blank=True
|
||||||
)
|
)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
# Generated by Django 4.1 on 2022-08-23 15:54
|
# Generated by Django 4.1 on 2022-08-23 15:54
|
||||||
|
|
||||||
import ckeditor_uploader.fields
|
# ckeditor removal
|
||||||
|
# import ckeditor_uploader.fields
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
@@ -11,9 +12,9 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="consist",
|
# model_name="consist",
|
||||||
name="notes",
|
# name="notes",
|
||||||
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True),
|
# field=ckeditor_uploader.fields.RichTextUploadingField(blank=True),
|
||||||
),
|
# ),
|
||||||
]
|
]
|
||||||
|
19
ram/consist/migrations/0010_alter_consist_notes.py
Normal file
19
ram/consist/migrations/0010_alter_consist_notes.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("consist", "0009_alter_consist_image"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="consist",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -4,7 +4,7 @@ from uuid import uuid4
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
from metadata.models import Company, Tag
|
from metadata.models import Company, Tag
|
||||||
@@ -26,7 +26,7 @@ class Consist(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
# Generated by Django 4.1 on 2022-08-23 15:54
|
# Generated by Django 4.1 on 2022-08-23 15:54
|
||||||
|
|
||||||
import ckeditor.fields
|
# ckeditor dependency removal
|
||||||
import ckeditor_uploader.fields
|
# import ckeditor.fields
|
||||||
|
# import ckeditor_uploader.fields
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
@@ -12,24 +13,24 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="flatpage",
|
# model_name="flatpage",
|
||||||
name="content",
|
# name="content",
|
||||||
field=ckeditor_uploader.fields.RichTextUploadingField(),
|
# field=ckeditor_uploader.fields.RichTextUploadingField(),
|
||||||
),
|
# ),
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="siteconfiguration",
|
# model_name="siteconfiguration",
|
||||||
name="about",
|
# name="about",
|
||||||
field=ckeditor.fields.RichTextField(blank=True),
|
# field=ckeditor.fields.RichTextField(blank=True),
|
||||||
),
|
# ),
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="siteconfiguration",
|
# model_name="siteconfiguration",
|
||||||
name="footer",
|
# name="footer",
|
||||||
field=ckeditor.fields.RichTextField(blank=True),
|
# field=ckeditor.fields.RichTextField(blank=True),
|
||||||
),
|
# ),
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="siteconfiguration",
|
# model_name="siteconfiguration",
|
||||||
name="footer_extended",
|
# name="footer_extended",
|
||||||
field=ckeditor.fields.RichTextField(blank=True),
|
# field=ckeditor.fields.RichTextField(blank=True),
|
||||||
),
|
# ),
|
||||||
]
|
]
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("portal", "0016_remove_siteconfiguration_site_name"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="flatpage",
|
||||||
|
name="content",
|
||||||
|
field=tinymce.models.HTMLField(),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="about",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="footer",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="footer_extended",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -6,8 +6,7 @@ from django.dispatch.dispatcher import receiver
|
|||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from solo.models import SingletonModel
|
from solo.models import SingletonModel
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from tinymce import models as tinymce
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
|
||||||
|
|
||||||
from ram import __version__ as app_version
|
from ram import __version__ as app_version
|
||||||
from ram.utils import slugify
|
from ram.utils import slugify
|
||||||
@@ -15,7 +14,7 @@ from ram.utils import slugify
|
|||||||
|
|
||||||
class SiteConfiguration(SingletonModel):
|
class SiteConfiguration(SingletonModel):
|
||||||
site_author = models.CharField(max_length=256, blank=True)
|
site_author = models.CharField(max_length=256, blank=True)
|
||||||
about = RichTextField(blank=True)
|
about = tinymce.HTMLField(blank=True)
|
||||||
items_per_page = models.CharField(
|
items_per_page = models.CharField(
|
||||||
max_length=2,
|
max_length=2,
|
||||||
choices=[(str(x * 3), str(x * 3)) for x in range(2, 11)],
|
choices=[(str(x * 3), str(x * 3)) for x in range(2, 11)],
|
||||||
@@ -30,8 +29,8 @@ class SiteConfiguration(SingletonModel):
|
|||||||
],
|
],
|
||||||
default="type",
|
default="type",
|
||||||
)
|
)
|
||||||
footer = RichTextField(blank=True)
|
footer = tinymce.HTMLField(blank=True)
|
||||||
footer_extended = RichTextField(blank=True)
|
footer_extended = tinymce.HTMLField(blank=True)
|
||||||
show_version = models.BooleanField(default=True)
|
show_version = models.BooleanField(default=True)
|
||||||
use_cdn = models.BooleanField(default=True)
|
use_cdn = models.BooleanField(default=True)
|
||||||
extra_head = models.TextField(blank=True)
|
extra_head = models.TextField(blank=True)
|
||||||
@@ -56,7 +55,7 @@ class Flatpage(models.Model):
|
|||||||
name = models.CharField(max_length=256, unique=True)
|
name = models.CharField(max_length=256, unique=True)
|
||||||
path = models.CharField(max_length=256, unique=True)
|
path = models.CharField(max_length=256, unique=True)
|
||||||
published = models.BooleanField(default=False)
|
published = models.BooleanField(default=False)
|
||||||
content = RichTextUploadingField()
|
content = tinymce.HTMLField()
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from ram.utils import git_suffix
|
from ram.utils import git_suffix
|
||||||
|
|
||||||
__version__ = "0.9.6"
|
__version__ = "0.10.0"
|
||||||
__version__ += git_suffix(__file__)
|
__version__ += git_suffix(__file__)
|
||||||
|
@@ -44,8 +44,7 @@ INSTALLED_APPS = [
|
|||||||
"adminsortable2",
|
"adminsortable2",
|
||||||
"django_countries",
|
"django_countries",
|
||||||
"solo",
|
"solo",
|
||||||
"ckeditor",
|
"tinymce",
|
||||||
"ckeditor_uploader",
|
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
"ram",
|
"ram",
|
||||||
"portal",
|
"portal",
|
||||||
@@ -60,7 +59,7 @@ MIDDLEWARE = [
|
|||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
@@ -142,7 +141,23 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||||||
|
|
||||||
MEDIA_URL = "media/"
|
MEDIA_URL = "media/"
|
||||||
MEDIA_ROOT = STORAGE_DIR / "media"
|
MEDIA_ROOT = STORAGE_DIR / "media"
|
||||||
CKEDITOR_UPLOAD_PATH = "uploads/"
|
|
||||||
|
TINYMCE_DEFAULT_CONFIG = {
|
||||||
|
"height": "500px",
|
||||||
|
"menubar": False,
|
||||||
|
"plugins": "autolink lists link image charmap preview anchor "
|
||||||
|
"searchreplace visualblocks code fullscreen insertdatetime media "
|
||||||
|
"table paste code",
|
||||||
|
"toolbar": "undo redo | "
|
||||||
|
"bold italic underline strikethrough removeformat | "
|
||||||
|
"fontsizeselect formatselect | "
|
||||||
|
"alignleft aligncenter alignright alignjustify | "
|
||||||
|
"outdent indent numlist bullist | "
|
||||||
|
"insertfile image media pageembed template link anchor codesample | "
|
||||||
|
"charmap | "
|
||||||
|
"fullscreen preview code",
|
||||||
|
"images_upload_url": "/tinymce/upload_image",
|
||||||
|
}
|
||||||
|
|
||||||
COUNTRIES_OVERRIDE = {
|
COUNTRIES_OVERRIDE = {
|
||||||
"EU": "Europe",
|
"EU": "Europe",
|
||||||
|
@@ -13,6 +13,7 @@ Including another URLconf
|
|||||||
1. Import the include() function: from django.urls import include, path
|
1. Import the include() function: from django.urls import include, path
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
@@ -20,9 +21,12 @@ from django.conf.urls.static import static
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
|
from ram.views import UploadImage
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", lambda r: redirect("portal/")),
|
path("", lambda r: redirect("portal/")),
|
||||||
path("ckeditor/", include("ckeditor_uploader.urls")),
|
path("tinymce/", include("tinymce.urls")),
|
||||||
|
path("tinymce/upload_image", UploadImage.as_view(), name="upload_image"),
|
||||||
path("portal/", include("portal.urls")),
|
path("portal/", include("portal.urls")),
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("api/v1/consist/", include("consist.urls")),
|
path("api/v1/consist/", include("consist.urls")),
|
||||||
|
62
ram/ram/views.py
Normal file
62
ram/ram/views.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
import posixpath
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image, UnidentifiedImageError
|
||||||
|
|
||||||
|
from django.views import View
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import (
|
||||||
|
HttpResponseBadRequest,
|
||||||
|
HttpResponseForbidden,
|
||||||
|
JsonResponse,
|
||||||
|
)
|
||||||
|
from django.utils.text import slugify as slugify
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(csrf_exempt, name="dispatch")
|
||||||
|
class UploadImage(View):
|
||||||
|
def post(self, request, application=None, model=None):
|
||||||
|
if not request.user.is_authenticated:
|
||||||
|
raise HttpResponseForbidden()
|
||||||
|
|
||||||
|
file_obj = request.FILES["file"]
|
||||||
|
file_name, file_extension = os.path.splitext(file_obj.name)
|
||||||
|
file_name = slugify(file_name) + file_extension
|
||||||
|
|
||||||
|
try:
|
||||||
|
Image.open(file_obj)
|
||||||
|
except UnidentifiedImageError:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
today = datetime.date.today()
|
||||||
|
container = (
|
||||||
|
"uploads",
|
||||||
|
today.strftime("%Y"),
|
||||||
|
today.strftime("%m"),
|
||||||
|
today.strftime("%d"),
|
||||||
|
)
|
||||||
|
|
||||||
|
dir_path = os.path.join(settings.MEDIA_ROOT, *(p for p in container))
|
||||||
|
file_path = os.path.normpath(os.path.join(dir_path, file_name))
|
||||||
|
# even if we apply slugify to the file name, add more hardening
|
||||||
|
# to avoid any path transversal risk
|
||||||
|
if not file_path.startswith(str(settings.MEDIA_ROOT)):
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
||||||
|
with open(file_path, "wb+") as f:
|
||||||
|
for chunk in file_obj.chunks():
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
"message": "Image uploaded successfully",
|
||||||
|
"location": posixpath.join(
|
||||||
|
settings.MEDIA_URL, *(p for p in container), file_name
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
@@ -1,6 +1,7 @@
|
|||||||
# Generated by Django 4.1 on 2022-08-23 15:54
|
# Generated by Django 4.1 on 2022-08-23 15:54
|
||||||
|
|
||||||
import ckeditor_uploader.fields
|
# ckeditor removal
|
||||||
|
# import ckeditor_uploader.fields
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
@@ -11,9 +12,9 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
# migrations.AlterField(
|
||||||
model_name="rollingstock",
|
# model_name="rollingstock",
|
||||||
name="notes",
|
# name="notes",
|
||||||
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True),
|
# field=ckeditor_uploader.fields.RichTextUploadingField(blank=True),
|
||||||
),
|
# ),
|
||||||
]
|
]
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
# Generated by Django 4.1 on 2022-08-27 12:43
|
# Generated by Django 4.1 on 2022-08-27 12:43
|
||||||
|
|
||||||
import ckeditor_uploader.fields
|
# ckeditor removal
|
||||||
|
# import ckeditor_uploader.fields
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ class Migration(migrations.Migration):
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
("date", models.DateField()),
|
("date", models.DateField()),
|
||||||
("log", ckeditor_uploader.fields.RichTextUploadingField()),
|
# ("log", ckeditor_uploader.fields.RichTextUploadingField()),
|
||||||
|
("log", models.TextField()),
|
||||||
("private", models.BooleanField(default=False)),
|
("private", models.BooleanField(default=False)),
|
||||||
("creation_time", models.DateTimeField(auto_now_add=True)),
|
("creation_time", models.DateTimeField(auto_now_add=True)),
|
||||||
("updated_time", models.DateTimeField(auto_now=True)),
|
("updated_time", models.DateTimeField(auto_now=True)),
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("roster", "0021_alter_rollingstockdocument_file_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="rollingstock",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="rollingstockjournal",
|
||||||
|
name="log",
|
||||||
|
field=tinymce.models.HTMLField(),
|
||||||
|
),
|
||||||
|
]
|
@@ -7,7 +7,7 @@ from django.urls import reverse
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from ram.models import Document, Image, PropertyInstance
|
from ram.models import Document, Image, PropertyInstance
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
@@ -85,7 +85,7 @@ class RollingStock(models.Model):
|
|||||||
era = models.CharField(max_length=32, blank=True)
|
era = models.CharField(max_length=32, blank=True)
|
||||||
production_year = models.SmallIntegerField(null=True, blank=True)
|
production_year = models.SmallIntegerField(null=True, blank=True)
|
||||||
purchase_date = models.DateField(null=True, blank=True)
|
purchase_date = models.DateField(null=True, blank=True)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
tags = models.ManyToManyField(
|
tags = models.ManyToManyField(
|
||||||
Tag, related_name="rolling_stock", blank=True
|
Tag, related_name="rolling_stock", blank=True
|
||||||
)
|
)
|
||||||
@@ -175,7 +175,7 @@ class RollingStockJournal(models.Model):
|
|||||||
blank=False,
|
blank=False,
|
||||||
)
|
)
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
log = RichTextUploadingField()
|
log = tinymce.HTMLField()
|
||||||
private = models.BooleanField(default=False)
|
private = models.BooleanField(default=False)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
@@ -7,7 +7,7 @@ django-solo
|
|||||||
django-countries
|
django-countries
|
||||||
django-health-check
|
django-health-check
|
||||||
django-admin-sortable2
|
django-admin-sortable2
|
||||||
django-ckeditor
|
django-tinymce
|
||||||
# Optional: # psycopg2-binary
|
# Optional: # psycopg2-binary
|
||||||
# Optional: # pySerial
|
# Optional: # pySerial
|
||||||
# Required by django-countries and not always installed
|
# Required by django-countries and not always installed
|
||||||
|
Reference in New Issue
Block a user