Update StreamField usage to include JSON

This commit is contained in:
Ramon Wenger 2023-02-21 17:09:17 +01:00
parent 5033668b79
commit dee5880565
7 changed files with 179 additions and 72 deletions

View File

@ -0,0 +1,22 @@
# Generated by Django 3.2.16 on 2023-02-21 16:04
import books.blocks
from django.db import migrations
import wagtail.blocks
import wagtail.fields
import wagtail.images.blocks
class Migration(migrations.Migration):
dependencies = [
('basicknowledge', '0025_auto_20220914_1338'),
]
operations = [
migrations.AlterField(
model_name='basicknowledge',
name='contents',
field=wagtail.fields.StreamField([('text_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['bold', 'ul', 'brand', 'secondary']))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('link_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('video_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('document_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('section_title', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('infogram_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock()), ('title', wagtail.blocks.TextBlock())])), ('genially_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('thinglink_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('subtitle', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('cms_document_block', books.blocks.CMSDocumentBlock())], blank=True, null=True, use_json_field=True),
),
]

View File

@ -1,35 +1,44 @@
from django.db import models from django.db import models
from django.utils.text import slugify from django.utils.text import slugify
from wagtail.admin.panels import FieldPanel, StreamFieldPanel from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField, StreamField from wagtail.fields import RichTextField, StreamField
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from books.blocks import CMSDocumentBlock, DocumentBlock, GeniallyBlock, InfogramBlock, InstrumentTextBlock, LinkBlock, \ from books.blocks import (
SectionTitleBlock, \ CMSDocumentBlock,
SubtitleBlock, ThinglinkBlock, VideoBlock DocumentBlock,
GeniallyBlock,
InfogramBlock,
InstrumentTextBlock,
LinkBlock,
SectionTitleBlock,
SubtitleBlock,
ThinglinkBlock,
VideoBlock,
)
from core.constants import DEFAULT_RICH_TEXT_FEATURES from core.constants import DEFAULT_RICH_TEXT_FEATURES
from core.wagtail_utils import StrictHierarchyPage from core.wagtail_utils import StrictHierarchyPage
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
LANGUAGE_COMMUNICATION = 'language_communication' LANGUAGE_COMMUNICATION = "language_communication"
SOCIETY = 'society' SOCIETY = "society"
INTERDISCIPLINARY = 'interdisciplinary' INTERDISCIPLINARY = "interdisciplinary"
LANGUAGE_COMMUNICATION_LABEL = 'Sprache & Kommunikation' LANGUAGE_COMMUNICATION_LABEL = "Sprache & Kommunikation"
SOCIETY_LABEL = 'Gesellschaft' SOCIETY_LABEL = "Gesellschaft"
INTERDISCIPLINARY_LABEL = 'Überfachliche Instrumente' INTERDISCIPLINARY_LABEL = "Überfachliche Instrumente"
class InstrumentCategory(models.Model): class InstrumentCategory(models.Model):
name = models.CharField(max_length=255, unique=True) name = models.CharField(max_length=255, unique=True)
background = models.CharField('background color', max_length=7) background = models.CharField("background color", max_length=7)
foreground = models.CharField('foreground color', max_length=7) foreground = models.CharField("foreground color", max_length=7)
def __str__(self): def __str__(self):
return self.name return self.name
class Meta: class Meta:
verbose_name_plural = _('instrument categories') verbose_name_plural = _("instrument categories")
verbose_name = _('instrument category') verbose_name = _("instrument category")
def default_category(): def default_category():
@ -38,8 +47,8 @@ def default_category():
class InstrumentType(models.Model): class InstrumentType(models.Model):
class Meta: class Meta:
verbose_name = _('instrument type') verbose_name = _("instrument type")
verbose_name_plural = _('instrument types') verbose_name_plural = _("instrument types")
CATEGORY_CHOICES = ( CATEGORY_CHOICES = (
(LANGUAGE_COMMUNICATION, LANGUAGE_COMMUNICATION_LABEL), (LANGUAGE_COMMUNICATION, LANGUAGE_COMMUNICATION_LABEL),
@ -53,7 +62,7 @@ class InstrumentType(models.Model):
on_delete=models.PROTECT, on_delete=models.PROTECT,
null=False, null=False,
default=default_category, default=default_category,
related_name='instrument_types' related_name="instrument_types",
) )
@property @property
@ -64,42 +73,46 @@ class InstrumentType(models.Model):
return self.type return self.type
class BasicKnowledge(StrictHierarchyPage): class BasicKnowledge(StrictHierarchyPage):
class Meta: class Meta:
verbose_name = _('instrument') verbose_name = _("instrument")
verbose_name_plural = _('instruments') verbose_name_plural = _("instruments")
parent_page_types = ['books.book'] parent_page_types = ["books.book"]
intro = RichTextField(features=DEFAULT_RICH_TEXT_FEATURES, default='', blank=True) intro = RichTextField(
features=DEFAULT_RICH_TEXT_FEATURES, default="", blank=True)
contents = StreamField([ contents = StreamField(
('text_block', InstrumentTextBlock()), [
('image_block', ImageChooserBlock()), ("text_block", InstrumentTextBlock()),
('link_block', LinkBlock()), ("image_block", ImageChooserBlock()),
('video_block', VideoBlock()), ("link_block", LinkBlock()),
('document_block', DocumentBlock()), ("video_block", VideoBlock()),
('section_title', SectionTitleBlock()), ("document_block", DocumentBlock()),
('infogram_block', InfogramBlock()), ("section_title", SectionTitleBlock()),
('genially_block', GeniallyBlock()), ("infogram_block", InfogramBlock()),
('thinglink_block', ThinglinkBlock()), ("genially_block", GeniallyBlock()),
('subtitle', SubtitleBlock()), ("thinglink_block", ThinglinkBlock()),
('cms_document_block', CMSDocumentBlock()), ("subtitle", SubtitleBlock()),
], null=True, blank=True) ("cms_document_block", CMSDocumentBlock()),
],
null=True,
blank=True,
use_json_field=True,
)
new_type = models.ForeignKey(InstrumentType, null=True, on_delete=models.PROTECT, related_name='instruments') new_type = models.ForeignKey(
InstrumentType, null=True, on_delete=models.PROTECT, related_name="instruments"
)
old_type = models.CharField( old_type = models.CharField(
max_length=100, max_length=100, choices=InstrumentType.CATEGORY_CHOICES, blank=True
choices=InstrumentType.CATEGORY_CHOICES,
blank=True
) )
content_panels = [ content_panels = [
FieldPanel('title', classname="full title"), FieldPanel("title", classname="full title"),
FieldPanel('new_type'), FieldPanel("new_type"),
FieldPanel('intro'), FieldPanel("intro"),
StreamFieldPanel('contents') FieldPanel("contents"),
] ]

View File

@ -0,0 +1,26 @@
# Generated by Django 3.2.16 on 2023-02-21 16:04
import assignments.models
import books.blocks
from django.db import migrations
import surveys.models
import wagtail.blocks
import wagtail.documents.blocks
import wagtail.fields
import wagtail.images.blocks
import wagtail.snippets.blocks
class Migration(migrations.Migration):
dependencies = [
('books', '0040_module_hero_source'),
]
operations = [
migrations.AlterField(
model_name='contentblock',
name='contents',
field=wagtail.fields.StreamField([('text_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['ul', 'bold']))])), ('basic_knowledge', wagtail.blocks.StructBlock([('description', wagtail.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.blocks.PageChooserBlock(page_type=['basicknowledge.BasicKnowledge'], required=True))])), ('assignment', wagtail.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('link_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('solution', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['ul', 'bold'])), ('document', books.blocks.CMSDocumentBlock(required=False))])), ('video_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('document_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('infogram_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock()), ('title', wagtail.blocks.TextBlock())])), ('genially_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('thinglink_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('subtitle', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('instruction', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock(required=False)), ('text', wagtail.blocks.TextBlock(required=False)), ('document', wagtail.documents.blocks.DocumentChooserBlock(required=False))])), ('module_room_slug', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock())])), ('cms_document_block', books.blocks.CMSDocumentBlock()), ('content_list_item', wagtail.blocks.StreamBlock([('text_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['ul', 'bold']))])), ('basic_knowledge', wagtail.blocks.StructBlock([('description', wagtail.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.blocks.PageChooserBlock(page_type=['basicknowledge.BasicKnowledge'], required=True))])), ('assignment', wagtail.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('link_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('solution', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['ul', 'bold'])), ('document', books.blocks.CMSDocumentBlock(required=False))])), ('video_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('document_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('infogram_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock()), ('title', wagtail.blocks.TextBlock())])), ('genially_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('thinglink_block', wagtail.blocks.StructBlock([('id', wagtail.blocks.TextBlock())])), ('subtitle', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('instruction', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock(required=False)), ('text', wagtail.blocks.TextBlock(required=False)), ('document', wagtail.documents.blocks.DocumentChooserBlock(required=False))])), ('module_room_slug', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock())])), ('cms_document_block', books.blocks.CMSDocumentBlock())]))], blank=True, null=True, use_json_field=True),
),
]

View File

@ -5,7 +5,6 @@ from wagtail.admin.panels import (
FieldPanel, FieldPanel,
TabbedInterface, TabbedInterface,
ObjectList, ObjectList,
StreamFieldPanel,
) )
from wagtail.blocks import StreamBlock from wagtail.blocks import StreamBlock
from wagtail.fields import StreamField from wagtail.fields import StreamField
@ -100,6 +99,7 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
content_blocks + [("content_list_item", content_list_item)], content_blocks + [("content_list_item", content_list_item)],
null=True, null=True,
blank=True, blank=True,
use_json_field=True,
) )
type = models.CharField( type = models.CharField(
@ -108,7 +108,7 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
content_panels = [ content_panels = [
FieldPanel("title", classname="full title"), FieldPanel("title", classname="full title"),
FieldPanel("type"), FieldPanel("type"),
StreamFieldPanel("contents"), FieldPanel("contents"),
] ]
# #

View File

@ -2,7 +2,6 @@ from django.db import models
from django.utils import timezone from django.utils import timezone
from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList from wagtail.admin.panels import FieldPanel, TabbedInterface, ObjectList
from wagtail.fields import RichTextField from wagtail.fields import RichTextField
from wagtail.images.edit_handlers import ImageChooserPanel
from core.constants import DEFAULT_RICH_TEXT_FEATURES from core.constants import DEFAULT_RICH_TEXT_FEATURES
from core.wagtail_utils import StrictHierarchyPage, get_default_settings from core.wagtail_utils import StrictHierarchyPage, get_default_settings
@ -35,7 +34,7 @@ class Module(StrictHierarchyPage):
content_panels = [ content_panels = [
FieldPanel("title", classname="full title"), FieldPanel("title", classname="full title"),
FieldPanel("meta_title", classname="full title"), FieldPanel("meta_title", classname="full title"),
ImageChooserPanel("hero_image"), FieldPanel("hero_image"),
FieldPanel("hero_source"), FieldPanel("hero_source"),
FieldPanel("teaser"), FieldPanel("teaser"),
FieldPanel("intro"), FieldPanel("intro"),

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.16 on 2023-02-21 16:04
from django.db import migrations
import wagtail.blocks
import wagtail.fields
class Migration(migrations.Migration):
dependencies = [
('rooms', '0012_auto_20220712_1109'),
]
operations = [
migrations.AlterField(
model_name='roomentry',
name='contents',
field=wagtail.fields.StreamField([('text_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.RichTextBlock(features=['ul', 'bold']))])), ('image_url_block', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('link_block', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock()), ('url', wagtail.blocks.URLBlock())])), ('document_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())])), ('subtitle', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock())])), ('video_block', wagtail.blocks.StructBlock([('url', wagtail.blocks.URLBlock())]))], blank=True, null=True, use_json_field=True),
),
]

View File

@ -3,7 +3,13 @@ from django.db import models
from django_extensions.db.models import TitleSlugDescriptionModel from django_extensions.db.models import TitleSlugDescriptionModel
from wagtail.fields import StreamField from wagtail.fields import StreamField
from books.blocks import DocumentBlock, ImageUrlBlock, LinkBlock, SubtitleBlock, VideoBlock from books.blocks import (
DocumentBlock,
ImageUrlBlock,
LinkBlock,
SubtitleBlock,
VideoBlock,
)
from books.models import TextBlock from books.models import TextBlock
from core.mixins import GraphqlNodeMixin from core.mixins import GraphqlNodeMixin
from users.models import SchoolClass from users.models import SchoolClass
@ -11,38 +17,55 @@ from users.models import SchoolClass
class Room(TitleSlugDescriptionModel, GraphqlNodeMixin): class Room(TitleSlugDescriptionModel, GraphqlNodeMixin):
class Meta: class Meta:
verbose_name = 'Raum' verbose_name = "Raum"
verbose_name_plural = 'Räume' verbose_name_plural = "Räume"
school_class = models.ForeignKey(SchoolClass, blank=False, null=False, on_delete=models.CASCADE, school_class = models.ForeignKey(
related_name='rooms') SchoolClass,
blank=False,
null=False,
on_delete=models.CASCADE,
related_name="rooms",
)
appearance = models.CharField(blank=True, null=False, max_length=255) appearance = models.CharField(blank=True, null=False, max_length=255)
user_created = models.BooleanField(blank=False, null=False, default=True) user_created = models.BooleanField(blank=False, null=False, default=True)
restricted = models.BooleanField(default=False) restricted = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return f'{self.title} - {self.school_class}' return f"{self.title} - {self.school_class}"
class RoomEntry(TitleSlugDescriptionModel): class RoomEntry(TitleSlugDescriptionModel):
class Meta: class Meta:
verbose_name = 'Raumeintrag' verbose_name = "Raumeintrag"
verbose_name_plural = 'Raumeinträge' verbose_name_plural = "Raumeinträge"
room = models.ForeignKey(Room, blank=False, null=False, on_delete=models.CASCADE, related_name='room_entries') room = models.ForeignKey(
author = models.ForeignKey(get_user_model(), null=True, on_delete=models.CASCADE) Room,
blank=False,
null=False,
on_delete=models.CASCADE,
related_name="room_entries",
)
author = models.ForeignKey(
get_user_model(), null=True, on_delete=models.CASCADE)
contents = StreamField([ contents = StreamField(
('text_block', TextBlock()), [
('image_url_block', ImageUrlBlock()), ("text_block", TextBlock()),
('link_block', LinkBlock()), ("image_url_block", ImageUrlBlock()),
('document_block', DocumentBlock()), ("link_block", LinkBlock()),
('subtitle', SubtitleBlock()), ("document_block", DocumentBlock()),
('video_block', VideoBlock()) ("subtitle", SubtitleBlock()),
], null=True, blank=True) ("video_block", VideoBlock()),
],
null=True,
blank=True,
use_json_field=True,
)
def __str__(self): def __str__(self):
return f'RoomEntry {self.id}-{self.title}-{self.author}' return f"RoomEntry {self.id}-{self.title}-{self.author}"
def can_user_see_entry(self, user): def can_user_see_entry(self, user):
return user.is_superuser or self.room.school_class.is_user_in_schoolclass(user) return user.is_superuser or self.room.school_class.is_user_in_schoolclass(user)
@ -50,17 +73,21 @@ class RoomEntry(TitleSlugDescriptionModel):
class ModuleRoomSlug(TitleSlugDescriptionModel): class ModuleRoomSlug(TitleSlugDescriptionModel):
class Meta: class Meta:
verbose_name = 'Slug für Modul-Raum' verbose_name = "Slug für Modul-Raum"
verbose_name_plural = 'Slugs für Modul-Raum' verbose_name_plural = "Slugs für Modul-Raum"
def __str__(self): def __str__(self):
return f'ModuleRoomSlug {self.id}-{self.title}' return f"ModuleRoomSlug {self.id}-{self.title}"
class Comment(models.Model): class Comment(models.Model):
text = models.TextField() text = models.TextField()
room_entry = models.ForeignKey(RoomEntry, related_name='comments', on_delete=models.CASCADE) room_entry = models.ForeignKey(
owner = models.ForeignKey(get_user_model(), related_name='comments', on_delete=models.PROTECT) RoomEntry, related_name="comments", on_delete=models.CASCADE
)
owner = models.ForeignKey(
get_user_model(), related_name="comments", on_delete=models.PROTECT
)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):