class StandardPage(wagtail_models.Page): """ A standard content page. """ description = models.TextField(blank=True) excerpt = wagtail_fields.RichTextField(blank=True) authors = modelcluster_fields.ParentalManyToManyField("users.User") date = models.DateTimeField() featured_image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) body = wagtail_fields.StreamField([ ("heading", wagtail_blocks.CharBlock()), ("paragraph", wagtail_blocks.RichTextBlock()), ("section", SectionBlock()), ]) content_panels = wagtail_models.Page.content_panels + [ wagtail_panels.FieldPanel("description"), wagtail_panels.FieldPanel("excerpt"), wagtail_panels.FieldPanel("authors"), wagtail_panels.FieldPanel("date"), wagtail_image_panels.ImageChooserPanel("featured_image"), wagtail_panels.StreamFieldPanel("body"), ]
class ProjectPage(Page): image = models.ForeignKey('images.CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') start_date = models.DateField() end_date = models.DateField() short_description = models.CharField(max_length=112, help_text=_('Shown in list.')) description = fields.RichTextField() embed_code = models.TextField() content_panels = Page.content_panels + [ edit_handlers.FieldPanel('short_description'), edit_handlers.FieldPanel('description'), ImageChooserPanel('image'), edit_handlers.FieldPanel('start_date'), edit_handlers.FieldPanel('end_date'), edit_handlers.FieldPanel('embed_code'), ] class Meta: verbose_name = _('Project') parent_page_types = ['ProjectContainerPage'] subpage_types = []
class Task(ClusterableModel): title = models.CharField( 'Название', max_length=80, blank=True ) # TODO - make required text = models.TextField('Текст', max_length=1024, blank=True) channel = models.CharField('Канал', default='space_bot', max_length=40) objects = TaskManager() panels = [ edit_handlers.FieldPanel('title'), edit_handlers.FieldPanel('text'), edit_handlers.FieldPanel('channel'), edit_handlers.InlinePanel('schedules', label='Расписание'), ] class Meta: verbose_name = 'Задача' verbose_name_plural = 'Задачи' def __str__(self): return self.title or self.text def days_string(self): return ','.join(str(s) for s in self.schedules.all()) days_string.short_description = 'Расписание'
class HomePage(Page): body = fields.StreamField([ ('paragraph', blocks.RichTextBlock()), ('call_to_action', cms_blocks.CallToActionBlock()), ('image_call_to_action', cms_blocks.ImageCallToActionBlock()), ('columns_text', cms_blocks.ColumnsBlock()), ('accordion', cms_blocks.DocsBlock()) ]) subtitle = models.CharField(max_length=120, blank=True) header_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') content_panels = [ edit_handlers.FieldPanel('title'), edit_handlers.FieldPanel('subtitle'), ImageChooserPanel('header_image'), edit_handlers.StreamFieldPanel('body') ] subpage_types = ['cms_home.SimplePage']
class SimplePage(Page): body = fields.RichTextField(blank=True) content_panels = [ edit_handlers.FieldPanel('title'), edit_handlers.FieldPanel('body'), ]
class Storefront(ClusterableModel): title = models.CharField(max_length=255, null=False, blank=False) image = models.ForeignKey('meinberlin_cms.CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') teaser = models.CharField(max_length=100) def __str__(self): return self.title @cached_property def num_entries(self): num_comments = Comment.objects.all().count() num_items = Item.objects.all().count() return num_comments + num_items @cached_property def num_projects(self): projects = Project.objects.all()\ .filter(is_draft=False, is_archived=False, is_public=True) active_project_count = 0 for project in projects: if project.active_phase or project.future_phases: active_project_count += 1 return active_project_count @cached_property def random_items(self): items = self.items.all() if items.count() > 3: items_list = items.values_list('id', flat=True) random_items = random.sample(list(items_list), 3) return StorefrontItem.objects.filter(id__in=random_items) else: return items title_panel = [edit_handlers.FieldPanel('title')] image_tile_panel = [ ImageChooserPanel('image'), edit_handlers.FieldPanel('teaser') ] project_tiles_panel = [edit_handlers.InlinePanel('items', min_num=3)] edit_handler = edit_handlers.TabbedInterface([ edit_handlers.ObjectList(title_panel, heading='Title'), edit_handlers.ObjectList(image_tile_panel, heading='Image Tile'), edit_handlers.ObjectList(project_tiles_panel, heading='Project Tiles') ])
class Line(models.Model): """ Random poem line returned in the header. """ text = models.CharField(max_length=500) is_published = models.BooleanField(blank=True, default=False) panels = [ wagtail_panels.FieldPanel("text"), wagtail_panels.FieldPanel("is_published"), ] def __str__(self): return self.text
class Grade(models.Model): code = models.CharField('Код', max_length=5) multiplier = models.FloatField('Повышающий коэффициент', default=1) panels = [ edit_handlers.FieldPanel('code'), edit_handlers.FieldPanel('multiplier'), ] def __str__(self): return self.code class Meta: verbose_name = 'Грейд' verbose_name_plural = 'Грейды'
class HomePage(Page): body = fields.StreamField([ ('paragraph', blocks.RichTextBlock( template='meinberlin_cms/blocks/richtext_block.html')), ('call_to_action', cms_blocks.CallToActionBlock()), ('image_call_to_action', cms_blocks.ImageCallToActionBlock()), ('columns_text', cms_blocks.ColumnsBlock()), ('projects', cms_blocks.ProjectsWrapperBlock()), ('activities', actions_blocks.PlatformActivityBlock()), ('accordion', cms_blocks.DocsBlock()), ('infographic', cms_blocks.InfographicBlock()), ('map_teaser', cms_blocks.MapTeaserBlock()) ]) subtitle = models.CharField(max_length=120) header_image = models.ForeignKey('meinberlin_cms.CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') storefront = models.ForeignKey('meinberlin_cms.Storefront', on_delete=models.SET_NULL, null=True, related_name='+') content_panels = Page.content_panels + [ edit_handlers.FieldPanel('subtitle'), ImageChooserPanel('header_image'), edit_handlers.StreamFieldPanel('body'), SnippetChooserPanel('storefront') ]
class ArchivePage(Page): body = fields.StreamField([ ('archive_list', ArchiveListBlock()), ]) description = models.CharField(max_length=200) image = models.ForeignKey( 'images.CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) content_panels = Page.content_panels + [ edit_handlers.FieldPanel('description'), image_handlers.ImageChooserPanel('image'), edit_handlers.StreamFieldPanel('body'), ] class Meta: verbose_name = _('Archive') parent_page_types = [ 'home.HomePage' ] subpage_types = []
class DocsPage(Page): image = models.ForeignKey( 'images.CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) body = fields.StreamField([ ('documents_list', DocsBlock()), ('Text', RichTextBlock()) ]) description = models.CharField(max_length=200) content_panels = Page.content_panels + [ ImageChooserPanel('image'), edit_handlers.FieldPanel('description'), edit_handlers.StreamFieldPanel('body'), ] class Meta: verbose_name = _('Documents') parent_page_types = [ 'home.HomePage' ] subpage_types = []
class TildaPage(models.Model): # imported fields - not editable path = models.CharField(max_length=255, unique=True, editable=False) body = models.TextField(default='', editable=False) title = models.CharField(max_length=1024, default='', editable=False) description = models.CharField(max_length=1024, default='', editable=False) page_id = models.IntegerField(editable=False, default=0) imported_dt = models.DateTimeField(blank=True, null=True) assets = models.ManyToManyField(Asset) # these fields are can be configured through Kocherga website show_header_and_footer = models.BooleanField(default=True) og_image = models.ForeignKey( 'kocherga_wagtail.CustomImage', on_delete=models.PROTECT, related_name='+', null=True, blank=True, ) objects = TildaPageManager() def __str__(self): return self.path def get_tilda_edit_link(self): return f'https://tilda.cc/page/?pageid={self.page_id}&projectid={settings.TILDA_PROJECT_ID}' panels = [ edit_handlers.FieldPanel('show_header_and_footer'), images_edit_handlers.ImageChooserPanel('og_image'), # TODO - show tilda edit link in custom panel ]
class Quote(models.Model): """ Random quote. """ source = models.CharField(max_length=300) quote = models.TextField() citation = models.CharField(max_length=300) is_published = models.BooleanField(blank=True, default=False) panels = [ wagtail_panels.FieldPanel("source"), wagtail_panels.FieldPanel("quote"), wagtail_panels.FieldPanel("citation"), wagtail_panels.FieldPanel("is_published"), ] def __str__(self): return f"{self.source}, {self.citation}"
class Schedule(models.Model): weekday = models.IntegerField( 'День недели', choices=( (0, 'Понедельник'), (1, 'Вторник'), (2, 'Среда'), (3, 'Четверг'), (4, 'Пятница'), (5, 'Суббота'), (6, 'Воскресенье'), ), ) period = models.IntegerField( 'Частота', default=1, help_text='Повторять каждые N недель' ) task = ParentalKey(Task, on_delete=models.CASCADE, related_name='schedules') panels = [ edit_handlers.FieldPanel('weekday'), edit_handlers.FieldPanel('period'), ] class Meta: verbose_name = 'Расписания' verbose_name_plural = 'Расписание' @property def weekday_short(self): return ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'][self.weekday] def check_date(self, d): if d.isocalendar()[1] % self.period: return False return d.weekday() == self.weekday def __str__(self): result = self.weekday_short if self.period != 1: result += '/' + str(self.period) return result
class NavigationMenu(ClusterableModel): title = models.CharField(max_length=255, null=False, blank=False) def __str__(self): return self.title panels = [ edit_handlers.FieldPanel('title'), edit_handlers.InlinePanel('items') ]
class NavigationMenu(ClusterableModel): menu_name = models.CharField(max_length=255, null=False, blank=False) def __str__(self): return self.menu_name panels = [ edit_handlers.FieldPanel('menu_name', classname='full title'), edit_handlers.InlinePanel('menu_items', label="Menu Items") ]
class StreamfieldSimplePage(Page): body = fields.StreamField([('paragraph', blocks.RichTextBlock()), ('html', blocks.RawHTMLBlock())], blank=True) content_panels = [ edit_handlers.FieldPanel('title'), edit_handlers.StreamFieldPanel('body'), ] subpage_types = []
class SimplePage(Page): body = fields.RichTextField(blank=True) body_block = fields.StreamField( [('text', blocks.RichTextBlock(icon='doc-full', template='home/blocks/text.html')), ('html', blocks.RawHTMLBlock(template='home/blocks/text.html')), ('teasers', TeaserListBlock()), ('columns', ColumnsListBlock()), ('projects', CurrentProjectsListBlock()), ('updates', UpdatesBlock())], blank=True) content_panels = [ edit_handlers.FieldPanel('title'), edit_handlers.FieldPanel('body'), edit_handlers.StreamFieldPanel('body_block'), ] parent_page_types = ['home.HomePage'] subpage_types = []
class EventPage(Page): date = models.DateField() time_start = models.TimeField() time_end = models.TimeField() place = models.CharField(max_length=32) contact = models.EmailField() short_description = models.CharField(max_length=112, help_text='Shown on the homepage.') description = RichTextField() content_panels = Page.content_panels + [ edit_handlers.MultiFieldPanel([ edit_handlers.FieldPanel('date'), edit_handlers.FieldRowPanel([ edit_handlers.FieldPanel('time_start'), edit_handlers.FieldPanel('time_end') ]), edit_handlers.FieldPanel('place'), edit_handlers.FieldPanel('contact'), ], heading='Key Data'), edit_handlers.MultiFieldPanel([ edit_handlers.RichTextFieldPanel('description'), edit_handlers.FieldPanel('short_description'), ], heading='Text'), ] class Meta: verbose_name = _('Event') parent_page_types = ['events.CalendarPage'] subpage_types = []
class BlogIndexPage(PaginatorMixin, Page): description = models.CharField(max_length=200) content_panels = Page.content_panels + [ edit_handlers.FieldPanel('description'), ] class Meta: verbose_name = _('Blog') parent_page_types = ['home.HomePage'] subpage_types = ['blog.BlogEntryPage']
class Category(models.Model): """ Category for posts and collections. """ name = models.CharField(max_length=100) slug = models.SlugField(max_length=100, allow_unicode=True, unique=True) description = models.TextField(blank=True) order = models.PositiveSmallIntegerField(blank=True, default=0) panels = [ wagtail_panels.FieldPanel("name"), wagtail_panels.FieldPanel("slug"), wagtail_panels.FieldPanel("description"), wagtail_panels.FieldPanel("order"), ] def __str__(self): return self.name class Meta: verbose_name_plural = "categories"
class HomePage(Page): body = fields.StreamField([ ('paragraph', blocks.RichTextBlock()), ('background', cms_blocks.BackgroundBlock()), ('call_to_action', cms_blocks.CallToActionBlock()), ('image_call_to_action', cms_blocks.ImageCallToActionBlock()), ('columns_text', cms_blocks.ColumnsBlock()), ('accordion', cms_blocks.DocsBlock()) ]) subtitle = models.CharField(max_length=120, blank=True) header_image = models.ImageField(blank=True) content_panels = [ edit_handlers.FieldPanel('title'), edit_handlers.FieldPanel('subtitle'), edit_handlers.FieldPanel('header_image'), edit_handlers.StreamFieldPanel('body') ] subpage_types = ['cms_home.SimplePage']
class HomePage(RoutablePageMixin, Page): template = 'home/home_page.html' banner_title = models.CharField(max_length=100, null=True, blank=True) banner_subtitle = fields.RichTextField( features=["bold", "italic", "image"], null=True, blank=True) banner_image = models.ForeignKey("wagtailimages.Image", on_delete=models.SET_NULL, null=True, blank=True, related_name="image") banner_cta = models.ForeignKey("wagtailcore.Page", on_delete=models.SET_NULL, null=True, blank=True, related_name="link") staff_card = fields.StreamField([ ("cards", blocks.CardBlock()), ], null=True, blank=True) api_fields = [ banner_title, banner_subtitle, banner_image, banner_cta, staff_card ] content_panels = Page.content_panels + [ eh.FieldPanel("banner_title"), eh.FieldPanel("banner_subtitle"), ImageChooserPanel("banner_image"), eh.PageChooserPanel("banner_cta"), eh.StreamFieldPanel("staff_card"), ] class Meta: verbose_name = "HOME PAGE" verbose_name_plural = "HOME PAGES"
class Testimonial(Orderable, models.Model): author_image = models.ForeignKey( 'kocherga_wagtail.CustomImage', null=True, blank=True, on_delete=models.PROTECT, related_name='+', ) author_name = models.CharField(max_length=80) author_description = models.CharField(max_length=1024, blank=True) text = RichTextField() product = models.ForeignKey( TestimonialProduct, null=True, blank=True, on_delete=models.SET_NULL, related_name='testimonials', ) objects = RelayQuerySet.as_manager() def __str__(self): return self.author_name class Meta: verbose_name = 'Отзыв' verbose_name_plural = 'Отзывы' panels = [ ImageChooserPanel('author_image'), edit_handlers.FieldPanel('author_name'), edit_handlers.FieldPanel('author_description'), SnippetChooserPanel('product'), edit_handlers.FieldPanel('text'), ]
class ServicesPage(Page): intro = models.TextField(null=True, blank=True) body = fields.StreamField( blocks.StreamBlock( [('section', SectionBlock())], min_num=4, max_num=4, ), blank=False, ) content_panels = Page.content_panels + [ edit_handlers.FieldPanel("intro"), edit_handlers.StreamFieldPanel("body"), ]
class EmailFormPage(AbstractEmailForm): intro = fields.RichTextField( help_text='Introduction text shown above the form') thank_you = fields.RichTextField( help_text='Text shown after form submission', ) email_content = models.CharField( max_length=200, help_text='Email content message', ) attach_as = models.CharField( max_length=3, choices=( ('inc', 'Include in Email'), ('xls', 'XLSX Document'), ('txt', 'Text File'), ), default='inc', help_text='Form results are send in this document format', ) content_panels = AbstractEmailForm.content_panels + [ edit_handlers.MultiFieldPanel([ edit_handlers.FieldPanel('intro', classname='full'), edit_handlers.FieldPanel('thank_you', classname='full'), ], 'Page'), edit_handlers.MultiFieldPanel([ edit_handlers.FieldPanel('to_address'), edit_handlers.FieldPanel('subject'), edit_handlers.FieldPanel('email_content', classname='full'), edit_handlers.FieldPanel('attach_as'), ], 'Email'), edit_handlers.InlinePanel('form_fields', label='Form fields'), ] def send_mail(self, form): kwargs = { 'title': self.title.replace(' ', '_'), 'to_addresses': self.to_address.split(','), 'field_values': self.get_field_values(form), 'submission_pk': self.get_submission_class().objects.last().pk } if self.attach_as == 'xls': emails.XlsxFormEmail.send(self, **kwargs) elif self.attach_as == 'txt': emails.TextFormEmail.send(self, **kwargs) else: emails.FormEmail.send(self, **kwargs) def get_field_values(self, form): fields = {} for field in form: value = field.value() if isinstance(value, list): value = ', '.join(value) fields[field.label] = value return fields
class MenuItem(models.Model): title = models.CharField(max_length=255) link_page = models.ForeignKey('wagtailcore.Page', on_delete=models.CASCADE) @property def url(self): return self.link_page.url def __str__(self): return self.title panels = [ edit_handlers.FieldPanel('title'), edit_handlers.PageChooserPanel('link_page') ]
class CalendarPage(PaginatorMixin, Page): short_description = models.CharField(max_length=112, blank=True) objects_per_page = 12 def get_ordered_children(self): return EventPage.objects.descendant_of(self).order_by('date') class Meta: verbose_name = _('Calendar') parent_page_types = ['home.HomePage'] subpage_types = ['events.EventPage'] content_panels = Page.content_panels + [ edit_handlers.FieldPanel('short_description'), ]
class DocsPage(Page): body = fields.StreamField([ ('documents_list', cms_blocks.DocsBlock()), ('header', blocks.CharBlock(template='meinberlin_cms/blocks/header.html')) ]) description = fields.RichTextField(blank=True) content_panels = Page.content_panels + [ edit_handlers.FieldPanel('description'), edit_handlers.StreamFieldPanel('body'), ] class Meta: verbose_name = 'Documents' subpage_types = []
class Post(wagtail_models.Page): """ A standard post. """ description = models.TextField(blank=True) excerpt = wagtail_fields.RichTextField(blank=True) authors = modelcluster_fields.ParentalManyToManyField("users.User") date = models.DateTimeField() featured_image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) tags = modelcluster_taggit.ClusterTaggableManager( through="home.TaggedPost", blank=True) categories = modelcluster_fields.ParentalManyToManyField("home.Category", blank=True) body = wagtail_fields.StreamField([ ("heading", wagtail_blocks.CharBlock()), ("paragraph", wagtail_blocks.RichTextBlock()), ("section", SectionBlock()), ("image", wagtail_image_blocks.ImageChooserBlock()), ]) content_panels = wagtail_models.Page.content_panels + [ wagtail_panels.FieldPanel("description"), wagtail_panels.FieldPanel("excerpt"), wagtail_panels.FieldPanel("authors"), wagtail_panels.FieldPanel("date"), wagtail_panels.FieldPanel("tags"), wagtail_panels.FieldPanel("categories"), wagtail_image_panels.ImageChooserPanel("featured_image"), wagtail_panels.StreamFieldPanel("body"), ] parent_page_types = ["home.PostIndexPage"] subpage_types = [] def set_url_path(self, parent): super().set_url_path(parent=parent) self.url_path = self.url_path.replace( self.slug, "{:%Y/%b/%d/}".format(self.date).lower() + self.slug)