class SpotlightIndicator(Page): class Meta(): verbose_name = 'Spotlight Indicator' parent_page_types = [SpotlightTheme] ddw_id = models.CharField(max_length=255) description = models.TextField(help_text='A description of this indicator', null=True, blank=True) source = models.TextField(help_text='Where is the data from?', null=True, blank=True) color = models.ForeignKey( SpotlightColour, null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) start_year = models.IntegerField(blank=True, null=True) end_year = models.IntegerField(blank=True, null=True) excluded_years = models.TextField(help_text='Comma separated values e.g. 2002,2004,2017', blank=True, null=True) DATA_FORMAT_CHOICES = [ ('percent', 'Percentage'), ('plain', 'Plain'), ('currency', 'Currency') ] data_format = models.TextField( max_length=100, choices=DATA_FORMAT_CHOICES, default='plain', help_text='Options are plain, currency, percent') range = models.CharField(max_length=100, null=True, blank=True, help_text='The range of values shown on the legend') value_prefix = models.CharField(max_length=100, null=True, blank=True) value_suffix = models.CharField(max_length=100, null=True, blank=True) tooltip_template = models.TextField( blank=True, null=True, help_text='Text for the tooltip.Template strings can be used to substitute values e.g. {name}') config = StreamField( AceEditorStreamBlock(max_num=1, block_counts={'JSON': {'max_num':1}}), null=True, blank=True, verbose_name='JSON Config') content_panels = Page.content_panels + [ FieldPanel('ddw_id'), FieldPanel('description'), FieldPanel('source'), SnippetChooserPanel('color'), FieldPanel('start_year'), FieldPanel('end_year'), FieldPanel('excluded_years'), FieldPanel('data_format'), FieldPanel('range'), FieldPanel('value_prefix'), FieldPanel('value_suffix'), FieldPanel('tooltip_template'), StreamFieldPanel('config') ] search_fields = Page.search_fields + [ index.SearchField('ddw_id') ] def serve(self, request, *args, **kwargs): raise Http404() def serve_preview(self, request, mode_name): return self.get_parent().serve(request)
search_fields = Page.search_fields + [ index.SearchField('introduction'), index.SearchField('key_info'), index.SearchField('in_depth'), ] @property def feed_text(self): return self.search_description or self.introduction @property def siblings(self): return self.get_siblings().live().public().filter( show_in_menus=True).specific() class Meta: verbose_name = "Topic Page" PrimaryTopicPage.content_panels = Page.content_panels + [ FieldPanel('introduction'), StreamFieldPanel('key_info'), StreamFieldPanel('in_depth'), SnippetChooserPanel('call_to_action'), SnippetChooserPanel('mailing_list_signup'), InlinePanel('related_links', label="Related Links"), ] PrimaryTopicPage.promote_panels = Page.promote_panels + PromoteMixin.panels
class ContactDayAndDuration(Orderable, DayAndDuration): contact = ParentalKey(Contact, related_name='hours') content_panels = [ SnippetChooserPanel('day_and_duration'), ]
class SearchPage(Page): class Meta: managed = True verbose_name = 'Search' verbose_name_plural = 'Search Pages' image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='Homepage image') image_alt = models.CharField(max_length=100, null=True, blank=True, help_text='Alt tag for image') hero_text = models.CharField( max_length=100, null=True, blank=True, help_text='Marketing-speak about GRMI EDU (100 Characters Max)') featured_title = models.CharField( max_length=100, null=True, blank=True, verbose_name='Introduction Title', help_text='Title for intro copy (optional)') featured_copy = RichTextField( features=[ 'bold', 'italic', 'link', 'ol', 'ul', 'document-link', 'image' ], null=True, blank=True, verbose_name='Introductory Content Copy', help_text='Copy describing the program & the featured curricula') search_tag = models.TextField( null=True, blank=True, help_text='<app-root> tag plus modifiers like Program or modulesOnly') program = models.ForeignKey( 'taxonomy.Program', null=True, blank=True, on_delete=models.SET_NULL, ) content_panels = Page.content_panels + [ MultiFieldPanel([ ImageChooserPanel('image'), FieldPanel('image_alt'), FieldPanel('hero_text', classname="full"), ], heading="Hero Section"), MultiFieldPanel([ FieldPanel('featured_title'), FieldPanel('featured_copy'), ], heading="Introduction Section"), MultiFieldPanel([ FieldPanel('search_tag'), SnippetChooserPanel('program'), ], heading="Angular Application Tag") ] # Export fields over the API api_fields = [ APIField('image'), APIField('image_alt'), APIField('hero_text'), APIField('featured_title'), APIField('featured_copy'), APIField('search_tag'), APIField('program'), ] def serve(self, request): modules = Module.objects.all() self.modules = modules return super().serve(request)
class ContentPage(Page): class Meta: managed = True verbose_name = 'Content' verbose_name_plural = 'Content Pages' image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='Homepage image') image_alt = models.CharField(max_length=100, null=True, blank=True, help_text='Alt tag for image') hero_text = models.CharField( max_length=100, null=True, blank=True, help_text='Marketing-speak about GRMI EDU (100 Characters Max)') program = models.ForeignKey( 'taxonomy.Program', null=True, blank=True, on_delete=models.SET_NULL, ) featured_title = models.CharField( max_length=100, null=True, blank=True, verbose_name='Introduction Title', help_text='Title for intro copy (optional)') featured_copy = RichTextField( features=[ 'bold', 'italic', 'link', 'ol', 'ul', 'document-link', 'image' ], null=True, blank=True, verbose_name='Introductory Content Copy', help_text='Copy describing the program & the featured curricula') body = StreamField([ ('title', blocks.TitleBlock()), ('copy', wagtail_blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('asset', SnippetChooserBlock('assets.Asset')), ('activity', SnippetChooserBlock('activity.Activity')), ('document', DocumentChooserBlock()), ('embed', EmbedBlock()), ('header', HeaderBlock()), ('list', ListBlock()), ('image_text_overlay', ImageTextOverlayBlock()), ('cropped_images_with_text', CroppedImagesWithTextBlock()), ('list_with_images', ListWithImagesBlock()), ('thumbnail_gallery', ThumbnailGalleryBlock()), ('chart', ChartBlock()), ('map', MapBlock()), ], null=True, blank=True) content_panels = Page.content_panels + [ MultiFieldPanel([ ImageChooserPanel('image'), FieldPanel('image_alt'), FieldPanel('hero_text', classname="full"), ], heading="Hero section"), MultiFieldPanel([ FieldPanel('featured_title'), FieldPanel('featured_copy'), ], heading="Introduction Section", classname='wagtailuiplus__panel--collapsed'), MultiFieldPanel([ StreamFieldPanel('body'), SnippetChooserPanel('program'), ], heading="Body") ] # Export fields over the API api_fields = [ APIField('image'), APIField('image_alt'), APIField('hero_text'), APIField('featured_title'), APIField('featured_copy'), APIField('program'), APIField('body'), ] def serve(self, request): modules = Module.objects.all() self.modules = modules return super().serve(request)
class AnswerPage(CFGOVPage): """Page type for Ask CFPB answers.""" from ask_cfpb.models.django import Answer last_edited = models.DateField( blank=True, null=True, help_text="Change the date to today if you make a significant change.") question = models.TextField(blank=True) statement = models.TextField( blank=True, help_text=( "(Optional) Use this field to rephrase the question title as " "a statement. Use only if this answer has been chosen to appear " "on a money topic portal (e.g. /consumer-tools/debt-collection).")) short_answer = RichTextField(blank=True, features=['link', 'document-link'], help_text='Optional answer intro') answer_content = StreamField(ask_blocks.AskAnswerContent(), blank=True, verbose_name='Answer') answer_base = models.ForeignKey(Answer, blank=True, null=True, related_name='answer_pages', on_delete=models.SET_NULL) redirect_to_page = models.ForeignKey( 'self', blank=True, null=True, on_delete=models.SET_NULL, related_name='redirect_to_pages', help_text="Choose another AnswerPage to redirect this page to") featured = models.BooleanField( default=False, help_text=("Check to make this one of two featured answers " "on the landing page.")) featured_rank = models.IntegerField(blank=True, null=True) category = models.ManyToManyField( 'Category', blank=True, help_text=("Categorize this answer. " "Avoid putting into more than one category.")) search_tags = models.CharField( max_length=1000, blank=True, help_text="Search words or phrases, separated by commas") related_resource = models.ForeignKey(RelatedResource, blank=True, null=True, on_delete=models.SET_NULL) related_questions = ParentalManyToManyField( 'self', symmetrical=False, blank=True, related_name='related_question', help_text='Maximum of 3 related questions') portal_topic = ParentalManyToManyField( PortalTopic, blank=True, help_text='Limit to 1 portal topic if possible') primary_portal_topic = ParentalKey( PortalTopic, blank=True, null=True, on_delete=models.SET_NULL, related_name='primary_portal_topic', help_text=("Use only if assigning more than one portal topic, " "to control which topic is used as a breadcrumb.")) portal_category = ParentalManyToManyField(PortalCategory, blank=True) user_feedback = StreamField([ ('feedback', v1_blocks.Feedback()), ], blank=True) share_and_print = models.BooleanField( default=False, help_text="Include share and print buttons above answer.") content_panels = CFGOVPage.content_panels + [ MultiFieldPanel([ FieldPanel('last_edited'), FieldPanel('question'), FieldPanel('statement'), FieldPanel('short_answer') ], heading="Page content", classname="collapsible"), FieldPanel('share_and_print'), StreamFieldPanel('answer_content'), MultiFieldPanel([ SnippetChooserPanel('related_resource'), AutocompletePanel('related_questions', target_model='ask_cfpb.AnswerPage') ], heading="Related resources", classname="collapsible"), MultiFieldPanel([ FieldPanel('portal_topic', widget=forms.CheckboxSelectMultiple), FieldPanel('primary_portal_topic'), FieldPanel('portal_category', widget=forms.CheckboxSelectMultiple) ], heading="Portal tags", classname="collapsible"), MultiFieldPanel([FieldPanel('featured')], heading="Featured answer on Ask landing page", classname="collapsible"), MultiFieldPanel([ AutocompletePanel('redirect_to_page', target_model='ask_cfpb.AnswerPage') ], heading="Redirect to another answer", classname="collapsible"), MultiFieldPanel([StreamFieldPanel('user_feedback')], heading="User feedback", classname="collapsible collapsed"), ] sidebar = StreamField([ ('call_to_action', molecules.CallToAction()), ('related_links', molecules.RelatedLinks()), ('related_metadata', molecules.RelatedMetadata()), ('email_signup', organisms.EmailSignUp()), ('sidebar_contact', organisms.SidebarContactInfo()), ('rss_feed', molecules.RSSFeed()), ('social_media', molecules.SocialMedia()), ('reusable_text', v1_blocks.ReusableTextChooserBlock(ReusableText)), ], blank=True) sidebar_panels = [ StreamFieldPanel('sidebar'), ] search_fields = Page.search_fields + [ index.SearchField('answer_content'), index.SearchField('short_answer') ] edit_handler = TabbedInterface([ ObjectList(content_panels, heading='Content'), ObjectList(sidebar_panels, heading='Sidebar'), ObjectList(CFGOVPage.settings_panels, heading='Configuration'), ]) template = 'ask-cfpb/answer-page.html' objects = CFGOVPageManager() def get_sibling_url(self): if self.answer_base: if self.language == 'es': sibling = self.answer_base.english_page else: sibling = self.answer_base.spanish_page if sibling and sibling.live and not sibling.redirect_to_page: return sibling.url def get_context(self, request, *args, **kwargs): portal_topic = self.primary_portal_topic or self.portal_topic.first() context = super(AnswerPage, self).get_context(request) context['related_questions'] = self.related_questions.all() context['description'] = (self.short_answer if self.short_answer else truncate_preview(self.answer_content)) context['last_edited'] = self.last_edited context['portal_page'] = get_portal_or_portal_search_page( portal_topic, language=self.language) context['breadcrumb_items'] = get_ask_breadcrumbs( language=self.language, portal_topic=portal_topic, ) context['about_us'] = get_standard_text(self.language, 'about_us') context['disclaimer'] = get_standard_text(self.language, 'disclaimer') context['sibling_url'] = self.get_sibling_url() return context def answer_content_text(self): raw_text = extract_raw_text(self.answer_content.stream_data) return strip_tags(" ".join([self.short_answer, raw_text])) def answer_content_data(self): return truncate_preview(self.answer_content_text()) def short_answer_data(self): return ' '.join( RichTextField.get_searchable_content(self, self.short_answer)) def text(self): short_answer = self.short_answer_data() answer_text = self.answer_content_text() full_text = f"{short_answer}\n\n{answer_text}\n\n{self.question}" return full_text def __str__(self): if self.answer_base: return f"{self.answer_base.id}: {self.title}" else: return self.title @property def clean_search_tags(self): return [tag.strip() for tag in self.search_tags.split(",")] @property def status_string(self): if self.redirect_to_page: if not self.live: return ("redirected but not live") else: return ("redirected") else: return super(AnswerPage, self).status_string # Returns an image for the page's meta Open Graph tag @property def meta_image(self): if self.social_sharing_image: return self.social_sharing_image if not self.category.exists(): return None return self.category.first().category_image # Overrides the default of page.id for comparing against split testing # clusters. See: core.feature_flags.in_split_testing_cluster @property def split_test_id(self): return self.answer_base.id
class BanneredCampaignPage(PrimaryPage): """ title, header, intro, and body are inherited from PrimaryPage """ # Note that this is a different related_name, as the `page` # name is already taken as back-referenced to CampaignPage. cta = models.ForeignKey( 'Petition', related_name='bcpage', blank=True, null=True, on_delete=models.SET_NULL, help_text='Choose an existing, or create a new, pettition form') signup = models.ForeignKey( 'Signup', related_name='bcpage', blank=True, null=True, on_delete=models.SET_NULL, help_text='Choose an existing, or create a new, sign-up form') tags = ClusterTaggableManager(through=BanneredCampaignTag, blank=True) panel_count = len(PrimaryPage.content_panels) n = panel_count - 1 content_panels = PrimaryPage.content_panels[:n] + [ SnippetChooserPanel('cta'), SnippetChooserPanel('signup'), ] + PrimaryPage.content_panels[n:] promote_panels = FoundationMetadataPageMixin.promote_panels + [ FieldPanel('tags'), ] translatable_fields = [ # Promote tab fields SynchronizedField('slug'), TranslatableField('seo_title'), SynchronizedField('show_in_menus'), TranslatableField('search_description'), SynchronizedField('search_image'), # Content tab fields TranslatableField('header'), TranslatableField('intro'), TranslatableField('body'), TranslatableField("title"), SynchronizedField("banner"), SynchronizedField("narrowed_page_content"), SynchronizedField("zen_nav"), TranslatableField("cta"), TranslatableField("signup"), ] subpage_types = [ 'BanneredCampaignPage', 'RedirectingPage', 'PublicationPage', 'OpportunityPage', 'ArticlePage' ] show_in_menus_default = True def get_context(self, request): context = super().get_context(request) context['related_posts'] = get_content_related_by_tag(self) return get_page_tree_information(self, context) class Meta: verbose_name = "Banner Page" verbose_name_plural = "Banner pages"
class RegistrationFormPage(AbstractEmailForm): # When creating a new Form page in Wagtail registration_head = models.CharField(null=True, blank=False, max_length=255) registration_newsletter_text = models.CharField(null=True, blank=False, max_length=255) registration_privacy_text = RichTextField(null=True, blank=False, features=['bold', 'italic', 'underline', 'strikethrough', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'ol', 'ul', 'hr', 'embed', 'link', 'superscript', 'subscript', 'document-link', 'image', 'code']) registration_info_text = RichTextField(null=True, blank=False, features=['bold', 'italic', 'underline', 'strikethrough', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'ol', 'ul', 'hr', 'embed', 'link', 'superscript', 'subscript', 'document-link', 'image', 'code']) registration_button = models.ForeignKey( 'home.Button', null=True, blank=False, on_delete=models.SET_NULL, related_name='+' ) registration_step_text = RichTextField(null=True, blank=False, features=['bold', 'italic', 'underline', 'strikethrough', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'ol', 'ul', 'hr', 'embed', 'link', 'superscript', 'subscript', 'document-link', 'image', 'code']) thank_you_text = RichTextField(null=True, blank=False, features=['bold', 'italic', 'underline', 'strikethrough', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'ol', 'ul', 'hr', 'embed', 'link', 'superscript', 'subscript', 'document-link', 'image', 'code']) supported_gitlabs = StreamField([ ('gitlab_server', Gitlab_Server(null=True, blank=False, icon='home')), ], null=True, blank=False) content_panels = AbstractEmailForm.content_panels + [ MultiFieldPanel( [ FieldPanel('registration_head', classname="full title"), FieldPanel('registration_newsletter_text', classname="full"), FieldPanel('registration_privacy_text', classname="full"), FieldPanel('registration_info_text', classname="full"), FieldPanel('registration_step_text', classname="full"), SnippetChooserPanel('registration_button', classname="full"), FieldPanel('thank_you_text', classname="full"), StreamFieldPanel('supported_gitlabs'), ], heading="content", ), MultiFieldPanel( [ FieldRowPanel([ FieldPanel('from_address', classname="col6"), FieldPanel('to_address', classname="col6"), ]), FieldPanel("subject"), ], heading="Email Settings" ), MultiFieldPanel( [ InlinePanel('form_fields', label="Form fields") ], heading="data", ) ] def get_submission_class(self): return RegistrationFormSubmission # Create a new user def create_user(self, username, customer_id, birthdate, telephone, address, city, postal_code, email, country, newsletter, platform_data, education_data, sources, verified, password, registration_data): # enter the data here user = get_user_model()( username=username, is_customer=True, customer_id=customer_id, birthdate=birthdate, telephone=telephone, address=address, city=city, postal_code=postal_code, email=email, country=country, newsletter=newsletter, platform_data=platform_data, education_data=education_data, sources=sources, verified=verified, registration_data=registration_data, ) user.set_password(password) user.save() return user # Called when a user registers def send_mail(self, form): addresses = [x.strip() for x in self.to_address.split(',')] emailheader = "New registration via Pharmaziegasse Website" content = [] for field in form: value = field.value() if isinstance(value, list): value = ', '.join(value) content.append('{}: {}'.format(field.label, value)) content = '\n'.join(content) content += '\n\nMade with ❤ by a tiny SNEK' #emailfooter = '<style>@keyframes pulse { 10% { color: red; } }</style><p>Made with <span style="width: 20px; height: 1em; color:#dd0000; animation: pulse 1s infinite;">❤</span> by <a style="color: lightgrey" href="https://www.aichner-christian.com" target="_blank">Werbeagentur Christian Aichner</a></p>' #html_message = f"{emailheader}\n\n{content}\n\n{emailfooter}" send_mail(self.subject, f"{emailheader}\n\n{content}", addresses, self.from_address) def process_form_submission(self, form): user=self.create_user( username=form.cleaned_data['username'], customer_id=form.cleaned_data['customer_id'], birthdate=form.cleaned_data['birthdate'], telephone=form.cleaned_data['telephone'], address=form.cleaned_data['address'], city=form.cleaned_data['city'], postal_code=form.cleaned_data['postal_code'], email=form.cleaned_data['email'], country=form.cleaned_data['country'], newsletter=form.cleaned_data['newsletter'], platform_data=form.cleaned_data['platform_data'], education_data=form.cleaned_data['education_data'], sources=form.cleaned_data['sources'], verified=form.cleaned_data['verified'], password=form.cleaned_data['password'], registration_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder), ) self.get_submission_class().objects.create( form_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder), page=self, user=user, ) if self.to_address: self.send_mail(form) preview_modes = []
tags = ClusterTaggableManager(through=PersonPageTag, blank=True) image = models.ForeignKey(Image, null=True, blank=True, on_delete=models.SET_NULL, related_name='+') feed_image = models.ForeignKey(Image, null=True, blank=True, on_delete=models.SET_NULL, related_name='+') indexed_fields = ('title', 'intro', 'biography') PersonPage.content_panels = [ FieldPanel('title', classname="title"), SnippetChooserPanel('role'), FieldPanel('intro', classname="full"), FieldPanel('biography', classname="full"), ImageChooserPanel('image'), FieldPanel('tags'), MultiFieldPanel(ContactFields.panels, "Contact"), InlinePanel('related_links', label="Related links"), ] PersonPage.promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ImageChooserPanel('feed_image'), ]
class BlogPage(HeadlessPreviewMixin, Page): date = models.DateField("Post date") advert = models.ForeignKey( "home.Advert", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) cover = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) book_file = models.ForeignKey( "wagtaildocs.Document", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) featured_media = models.ForeignKey( "wagtailmedia.Media", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) author = models.ForeignKey(AuthorPage, null=True, blank=True, on_delete=models.SET_NULL, related_name="+") body = StreamField(StreamFieldBlock()) content_panels = Page.content_panels + [ FieldPanel("date"), ImageChooserPanel("cover"), StreamFieldPanel("body"), InlinePanel("related_links", label="Related links"), InlinePanel("authors", label="Authors"), FieldPanel("author"), SnippetChooserPanel("advert"), DocumentChooserPanel("book_file"), MediaChooserPanel("featured_media"), ] @property def copy(self): return self graphql_fields = [ GraphQLString("heading"), GraphQLString("date", required=True), GraphQLStreamfield("body"), GraphQLCollection( GraphQLForeignKey, "related_links", "home.blogpagerelatedlink", required=True, item_required=True, ), GraphQLCollection(GraphQLString, "related_urls", source="related_links.url"), GraphQLCollection(GraphQLString, "authors", source="authors.person.name"), GraphQLSnippet("advert", "home.Advert"), GraphQLImage("cover"), GraphQLDocument("book_file"), GraphQLMedia("featured_media"), GraphQLForeignKey("copy", "home.BlogPage"), GraphQLPage("author"), ]
class PresentationPage(Page): is_featured = models.BooleanField() cover_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', ) date = models.DateField("Presentation date") date_fmt = models.CharField("Date format", max_length=8, choices=DATEFMT, default='YMD') abstract = RichTextField(blank=True, null=True) extra = RichTextField(blank=True, null=True) tags = ClusterTaggableManager(through=PresentationPageTag, blank=True) presentor = models.ForeignKey( 'home.Person', null=True, blank=True, on_delete=models.PROTECT, related_name='+', ) meeting = models.CharField(max_length=512) country = models.CharField(max_length=256, blank=True, null=True) location = models.CharField(max_length=256, blank=True, null=True) presentation_type = models.CharField(max_length=64, choices=PRESENTATIONTYPE, blank=True, null=True) category = models.ForeignKey( 'publication.Category', null=True, blank=True, on_delete=models.PROTECT, related_name='+', ) content_panels = Page.content_panels + [ FieldPanel('is_featured'), ImageChooserPanel('cover_image'), SnippetChooserPanel('presentor'), MultiFieldPanel([ FieldRowPanel([ FieldPanel('meeting', classname="col10"), ]), FieldRowPanel([ FieldPanel('country', classname="col6"), FieldPanel('location', classname="col6"), ]), FieldRowPanel([ FieldPanel('presentation_type', classname="col6"), FieldPanel('category', classname="col6"), ]) ], "Meeting information"), FieldPanel('date_fmt'), FieldPanel('date'), FieldPanel('tags'), FieldPanel('abstract', classname="full"), FieldPanel('extra', classname="full"), ] subpage_types = [] parent_page_types = [ 'PresentationsIndexPage', ]
class FacultyResources(models.Model): resource = models.ForeignKey( FacultyResource, null=True, help_text="Manage resources through snippets.", related_name='+', on_delete=models.SET_NULL) def get_resource_heading(self): return self.resource.heading resource_heading = property(get_resource_heading) def get_resource_description(self): return self.resource.description resource_description = property(get_resource_description) def get_resource_unlocked(self): return self.resource.unlocked_resource resource_unlocked = property(get_resource_unlocked) def get_resource_creator_fest_resource(self): return self.resource.creator_fest_resource creator_fest_resource = property(get_resource_creator_fest_resource) link_external = models.URLField("External link", blank=True) link_page = models.ForeignKey('wagtailcore.Page', null=True, blank=True, related_name='+', on_delete=models.SET_NULL) link_document = models.ForeignKey('wagtaildocs.Document', null=True, blank=True, related_name='+', on_delete=models.SET_NULL) def get_link_document(self): return build_document_url(self.link_document.url) link_document_url = property(get_link_document) def get_document_title(self): return self.link_document.title link_document_title = property(get_document_title) link_text = models.CharField(max_length=255, help_text="Call to Action Text") api_fields = ( 'resource_heading', 'resource_description', 'resource_unlocked', 'creator_fest_resource', 'link_external', 'link_page', 'link_document_url', 'link_document_title', 'link_text', ) panels = [ SnippetChooserPanel('resource'), FieldPanel('link_external'), PageChooserPanel('link_page'), DocumentChooserPanel('link_document'), FieldPanel('link_text'), ]
class BlogPage(Page): date = models.DateTimeField("Post Date") intro = models.CharField(max_length=250) description = models.TextField() body = models.TextField(blank=True) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) categories = ParentalManyToManyField('blog.BlogCategory', blank=True) advert = models.ForeignKey('blog.Advert', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') poll = models.ForeignKey('blog.Poll', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') author = models.ForeignKey( settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, related_name='author_pages', ) @property def blog_page(self): return self.get_parent().specific # def get_absolute_url(self): # # import pdb; pdb.set_trace() # return self.url def get_posts(self): # import pdb; pdb.set_trace() posts = BlogPage.objects.live()[:5] return posts def get_context(self, request, *args, **kwargs): context = super(BlogPage, self).get_context(request, *args, **kwargs) # import pdb; pdb.set_trace() context['posts'] = self context['blog_page'] = self.get_parent().specific context['top_stories'] = self.get_posts() context['COMMENTS_APP'] = COMMENTS_APP context['menuitems'] = self.get_children().filter( live=True, show_in_menus=True) return context def main_image(self): gallery_item = self.gallery_images.first() if gallery_item: return gallery_item.image else: return None search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel('date'), FieldPanel('tags'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), FieldPanel('poll') ], heading="Blog Information"), FieldPanel('date'), FieldPanel('intro'), FieldPanel('description'), FieldPanel('body', classname="full"), InlinePanel('gallery_images', label="Gallery images"), SnippetChooserPanel('advert'), ]
class BlocksPage(HeadlessPreviewMixin, PageBase): @property def description(self): element_descriptors = [ n.element_descriptor for n in self.blocks_page_element_descriptors_relationship.all() ] return element_descriptors what_it_does = models.ForeignKey( 'WhatItDoes', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='select a snippet from the what it does type', verbose_name='What it does', ) what_user_can_do = models.ForeignKey( 'WhatUserCanDo', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='select a snippet from the what user can do type', verbose_name='What user can do', ) when_to_use_it = models.ForeignKey( 'WhenToUseIt', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='select a snippet from the when to use it type', verbose_name='When to use it', ) cross_link = models.CharField(verbose_name="Cross Link", max_length=255, blank=True, help_text="i.e. button") demo_link = models.CharField( verbose_name="Demo Link", max_length=255, blank=True, help_text="i.e. code/ids-web/latest/demo/ids-button/index.html") fka = models.CharField(verbose_name="Formerly Known As", max_length=255, blank=True) types = StreamField( [('types', blocks.StructBlock([ ('name', blocks.CharBlock(required=True)), ('detail', blocks.CharBlock(required=True)), ('image', APIImageChooserBlock(required=False)), ('image', APIImageChooserBlock(required=False)), ('image_type', blocks.ChoiceBlock(choices=[('full-width', 'Full Width'), ('inline', 'Inline')], required=False)), ]))], null=True, blank=True) modifiers = StreamField( [ # @TODO: Figure out how to rename structblock # from `options` to `modifiers` ('options', blocks.StructBlock([('name', blocks.CharBlock(required=True)), ('detail', blocks.CharBlock(required=True)), ('token', blocks.CharBlock(required=False))])) ], null=True, blank=True) tokensCategory = models.CharField( verbose_name="Tokens Category", max_length=255, blank=True, ) body = StreamField([('image', APIImageChooserBlock()), ('heading', blocks.CharBlock(classname="full title")), ('richText', APIRichTextBlock()), ('markdown', APIMarkDownBlock())], null=True, blank=True) content_panels = Page.content_panels + [ FieldPanel('fka'), FieldPanel('cross_link'), FieldPanel('demo_link'), MultiFieldPanel([ SnippetChooserPanel('what_it_does'), SnippetChooserPanel('what_user_can_do'), SnippetChooserPanel('when_to_use_it') ]), StreamFieldPanel('types'), StreamFieldPanel('modifiers'), FieldPanel('tokensCategory'), StreamFieldPanel('body') ] api_fields = [ APIField('title'), APIField('fka'), APIField('cross_link'), APIField('demo_link'), APIField('descriptors', serializer=ElementDescriptorSerializer()), APIField('types'), APIField('modifiers'), APIField('tokensCategory'), APIField('body') ] def content(self): return "" search_fields = Page.search_fields + [ index.SearchField('body'), index.SearchField('what_it_does'), index.SearchField('what_user_can_do'), index.SearchField('when_to_use_it'), index.SearchField('fka'), index.SearchField('types'), index.SearchField('modifiers'), ]
def test_target_model_autodetected(self): result = SnippetChooserPanel('advert').bind_to_model( SnippetChooserModel).target_model self.assertEqual(result, Advert)
def test_target_model_autodetected(self): result = SnippetChooserPanel( 'advertwithcustomprimarykey').bind_to_model( SnippetChooserModelWithCustomPrimaryKey).target_model self.assertEqual(result, AdvertWithCustomPrimaryKey)