class StaticPage(Page): # TODO: Keep it simple for now. content = RichTextField(blank=True) language = models.CharField(max_length=7, choices=settings.LANGUAGES) def __str__(self): return self.title content_panels = Page.content_panels + [ FieldPanel('content'), FieldPanel('language'), ] search_fields = Page.search_fields + [ index.SearchField('title', partial_match=True, boost=SearchBoost.TITLE), index.SearchField('language'), index.FilterField('get_search_type'), index.FilterField('language'), index.SearchField('content') ] def get_search_type(self): return self.__class__.__name__.lower() def get_absolute_url(self): return reverse("static_page", kwargs={"slug": self.slug})
class FaqEntry(index.Indexed, models.Model): FAQ_CATEGORIES = Choices( ('abm', _('Agent-based Modeling Questions')), ('general', _('General CoMSES Net Questions')), ('model-library', _('Computational Model Library Questions')), ) category = models.CharField(max_length=32, choices=FAQ_CATEGORIES, default=FAQ_CATEGORIES.general) question = models.CharField(max_length=128, help_text=_("Short question")) answer = models.TextField(help_text=_("Markdown formatted answer")) date_created = models.DateTimeField(auto_now=True) last_modified = models.DateTimeField(auto_now_add=True) submitter = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL) search_fields = [ index.SearchField('category'), index.SearchField('question'), index.SearchField('answer'), index.FilterField('date_created'), index.FilterField('last_modified'), ] def __str__(self): return "[{0}] {1} {2}".format(self.category, self.question, shorten(self.answer, 140))
class Job(index.Indexed, ClusterableModel): title = models.CharField(max_length=300, help_text=_('Job posting title')) date_created = models.DateTimeField(default=timezone.now) application_deadline = models.DateField( blank=True, null=True, help_text=_('Optional deadline for applications')) last_modified = models.DateTimeField(auto_now=True) summary = models.CharField(max_length=500, blank=True, help_text=_('Brief summary of job posting.')) description = MarkdownField() tags = ClusterTaggableManager(through=JobTag, blank=True) external_url = models.URLField(blank=True) submitter = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='jobs', on_delete=models.SET(get_sentinel_user)) objects = JobQuerySet.as_manager() search_fields = [ index.SearchField('title', partial_match=True, boost=10), index.SearchField('description', partial_match=True), index.FilterField('date_created'), index.FilterField('last_modified'), index.FilterField('application_deadline'), index.RelatedFields('tags', [ index.SearchField('name'), ]), index.RelatedFields('submitter', [ index.SearchField('username'), index.SearchField('email', partial_match=True), index.SearchField('get_full_name', partial_match=True), ]), ] @property def live(self): return True def get_absolute_url(self): return reverse('home:job-detail', kwargs={'pk': self.pk}) @classmethod def get_list_url(cls): return reverse('home:job-list') def __str__(self): return "{0} posted by {1} on {2}".format( self.title, self.submitter.username, self.date_created.strftime('%c')) @property def owner(self): return self.submitter
class NewsPage(Page): title_sv = models.CharField(max_length=255) translated_title = TranslatedField('title', 'title_sv') body_en = RichTextField() body_sv = RichTextField() body = TranslatedField('body_en', 'body_sv') created = models.DateTimeField( verbose_name=_('Created at'), auto_now_add=True, ) modified = models.DateTimeField( verbose_name=_('Modified at'), auto_now=True, ) feed_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) # Search index configuration search_fields = Page.search_fields + [ index.SearchField('title_sv'), index.SearchField('body_en'), index.SearchField('body_sv'), index.FilterField('created'), index.FilterField('modified'), ] # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('body_en', classname="full"), ] content_panels_sv = [ FieldPanel('title_sv', classname="full title"), FieldPanel('body_sv', classname="full"), ] promote_panels = [ ImageChooserPanel('feed_image') ] + Page.promote_panels edit_handler = TabbedInterface([ ObjectList(content_panels, heading=_('English')), ObjectList(content_panels_sv, heading=_('Swedish')), ObjectList(promote_panels, heading=_('Promote')), ObjectList(Page.settings_panels, heading=_('Settings')), ]) # Parent page / sub-page type rules parent_page_types = ['news.NewsIndexPage'] subpage_types = []
class AbstractDocument(CollectionMember, index.Indexed, models.Model): title = models.CharField(max_length=255, verbose_name=_('title')) file = models.FileField(upload_to='documents', verbose_name=_('file')) created_at = models.DateTimeField(verbose_name=_('created at'), auto_now_add=True) uploaded_by_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('uploaded by user'), null=True, blank=True, editable=False, on_delete=models.SET_NULL) tags = TaggableManager(help_text=None, blank=True, verbose_name=_('tags')) objects = DocumentQuerySet.as_manager() search_fields = CollectionMember.search_fields + [ index.SearchField('title', partial_match=True, boost=10), index.FilterField('title'), index.RelatedFields('tags', [ index.SearchField('name', partial_match=True, boost=10), ]), index.FilterField('uploaded_by_user'), ] def __str__(self): return self.title @property def filename(self): return os.path.basename(self.file.name) @property def file_extension(self): return os.path.splitext(self.filename)[1][1:] @property def url(self): return reverse('wagtaildocs_serve', args=[self.id, self.filename]) def get_usage(self): return get_object_usage(self) @property def usage_url(self): return reverse('wagtaildocs:document_usage', args=(self.id, )) def is_editable_by_user(self, user): from wagtail.documents.permissions import permission_policy return permission_policy.user_has_permission_for_instance( user, 'change', self) class Meta: abstract = True verbose_name = _('document')
class Initiative(index.Indexed, Commentable, models.Model): title = models.CharField(max_length=250) description = models.TextField(blank=True) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) created_by = models.ForeignKey( User, blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) curated_by = models.ForeignKey( User, blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) class Status(models.TextChoices): ACTIVE = 'ACTIVE', 'Активный' INACTIVE = 'INACTIVE', 'Неактивный' status = models.CharField( max_length=20, choices=Status.choices, default='ACTIVE', db_index=True, ) leads = models.ManyToManyField(Lead, related_name='initiatives') event = models.ForeignKey( 'events.Event', on_delete=models.SET_NULL, related_name='community_initiatives', null=True, blank=True, ) objects = RelayQuerySet.as_manager() search_fields = [ index.SearchField('title', partial_match=True, boost=10), index.SearchField('description'), index.FilterField('status'), index.FilterField('curated_by_id'), ] class Meta: default_permissions = () ordering = ['-pk']
class GoogleFormPage(Page): title_sv = models.CharField(max_length=255) translated_title = TranslatedField('title', 'title_sv') # TODO: Limit to one form! form_en = StreamField([('google_form', GoogleFormBlock())]) form_sv = StreamField([('google_form', GoogleFormBlock())]) form = TranslatedField('form_en', 'form_sv') deadline = models.DateField(verbose_name=_('Form deadline')) results_en = StreamField( WAGTAIL_STATIC_BLOCKTYPES, blank=True, ) results_sv = StreamField( WAGTAIL_STATIC_BLOCKTYPES, blank=True, ) results = TranslatedField('results_en', 'results_sv') @property def is_past_due(self) -> bool: return date.today() > self.deadline # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('title_sv', classname="full title"), FieldPanel('deadline'), StreamFieldPanel('form_en'), StreamFieldPanel('form_sv'), ] edit_handler = TabbedInterface([ ObjectList(content_panels, heading=_('Common')), ObjectList([StreamFieldPanel('results_en')], heading=_('English')), ObjectList([StreamFieldPanel('results_sv')], heading=_('Swedish')), ObjectList( Page.promote_panels + Page.settings_panels, heading=_('Settings') ), ]) # Search index configuration search_fields = Page.search_fields + [ index.SearchField('title_sv'), index.FilterField('results_en'), index.FilterField('results_sv'), index.FilterField('deadline'), ] # Parent page / subpage type rules parent_page_types = ['google.GoogleFormIndex'] subpage_types = []
class Event(index.Indexed, ClusterableModel): title = models.CharField(max_length=300) date_created = models.DateTimeField(default=timezone.now) last_modified = models.DateTimeField(auto_now=True) summary = models.CharField(max_length=500, blank=True) description = MarkdownField() early_registration_deadline = models.DateTimeField(null=True, blank=True) registration_deadline = models.DateTimeField(null=True, blank=True) submission_deadline = models.DateTimeField(null=True, blank=True) start_date = models.DateTimeField() end_date = models.DateTimeField(null=True, blank=True) location = models.CharField(max_length=300) tags = ClusterTaggableManager(through=EventTag, blank=True) external_url = models.URLField(blank=True) objects = EventQuerySet.as_manager() submitter = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user)) search_fields = [ index.SearchField('title', partial_match=True, boost=10), index.SearchField('description', partial_match=True), index.FilterField('start_date'), index.FilterField('submission_deadline'), index.FilterField('early_registration_deadline'), index.FilterField('registration_deadline'), index.SearchField('location', partial_match=True), index.RelatedFields('tags', [ index.SearchField('name'), ]), index.RelatedFields('submitter', [ index.SearchField('username'), index.SearchField('email', partial_match=True), index.SearchField('get_full_name', partial_match=True), ]), ] @property def live(self): return True def get_absolute_url(self): return reverse('home:event-detail', kwargs={'pk': self.pk}) @classmethod def get_list_url(cls): return reverse('home:event-list') def __str__(self): return "{0} posted by {1} on {2}".format( self.title, self.submitter.username, self.date_created.strftime('%c'))
class Book(models.Model, index.Indexed): author = models.ForeignKey(Author, on_delete=models.PROTECT) title = models.CharField(max_length=255) cover_image = models.ForeignKey('wagtailimages.Image', on_delete=models.SET_NULL, null=True, blank=True) search_fields = [ index.SearchField('title'), index.FilterField('title'), index.FilterField('id'), ] def __str__(self): return self.title
class CategoryProxy(index.Indexed, get_model("catalogue", "Category")): search_fields = [ index.SearchField("name", partial_match=True, boost=2), index.AutocompleteField("name"), index.SearchField("description"), index.SearchField("full_name"), index.FilterField("full_slug"), index.FilterField("slug"), index.FilterField("get_absolute_url"), ] class Meta: proxy = True
class Lap(index.Indexed, models.Model): racer = models.ForeignKey(Racer, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) raceclass = models.ForeignKey(RaceClass, on_delete=models.CASCADE) car = models.ForeignKey(Car, blank=True,on_delete=models.CASCADE) event = models.ForeignKey(Event,null=True,blank=True, on_delete=models.CASCADE) region = models.ForeignKey(Region,null=True,blank=True, on_delete=models.CASCADE) track = models.ForeignKey(Track, on_delete=models.CASCADE) time = models.FloatField() lap_date = models.DateField("Lap date") best = models.BooleanField("Is Best?") @property def key(self): return "%s_%s_%s_%s_%s" % (self.racer.name, self.group.short_name, self.raceclass.short_name, self.track.short_name, self.lap_date) search_fields = [ index.FilterField('best'), index.FilterField('lap_date'), index.RelatedFields('racer', [ index.SearchField('name', partial_match=True), ]), index.RelatedFields('raceclass', [ index.SearchField('name', partial_match=True), ]), index.RelatedFields('track', [ index.SearchField('name', partial_match=True), ]), ] panels = [ FieldPanel('region', widget=forms.Select), FieldPanel('racer', widget=forms.Select), FieldPanel('raceclass', widget=forms.Select), FieldPanel('car', widget=forms.Select), FieldPanel('group', widget=forms.Select), FieldPanel('event', widget=forms.Select), FieldPanel('track', widget=forms.Select), FieldPanel('time'), FieldPanel('lap_date'), FieldPanel('best'), ] def __str__(self): return str(self.key) class Meta: verbose_name_plural = 'laps'
class ProjectsPage(Page): # db fields project_h_one = models.CharField(max_length=250, default="Project Name") project_h_two = models.CharField(max_length=250, default="Project Description") project_intro_p = models.TextField(blank=True) project_p = models.CharField(max_length=250, default="Project Launch Date") project_tech_stack_description = RichTextField(blank=True, features=["ul"]) project_url = models.URLField(max_length=200, default="Project URL") project_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') # Search index configuration search_fields = Page.search_fields + [ index.SearchField('project_h_one'), index.FilterField('project_h_two'), index.FilterField('project_intro_p'), index.FilterField('project_p'), index.FilterField('project_tech_stack_description'), ] # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('project_h_one'), FieldPanel('project_h_two', classname="full"), FieldPanel('project_intro_p', classname="full"), FieldPanel('project_p', classname="full"), FieldPanel('project_tech_stack_description', classname="full"), FieldPanel('project_url', classname="full"), ImageChooserPanel('project_image'), ] promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ] # API configuration api_fields = [ APIField('project_h_one'), APIField('project_h_two'), APIField('project_intro_p'), APIField('project_p'), APIField('project_tech_stack_description'), APIField('project_url'), APIField('project_image'), APIField('project_image_url', serializer=ImageRenditionField('fill-700x700', source='project_image')), ]
class Book(index.Indexed, models.Model): title = models.CharField(max_length=255) authors = models.ManyToManyField(Author, related_name='books') publication_date = models.DateField() number_of_pages = models.IntegerField() tags = TaggableManager() search_fields = [ index.SearchField('title', partial_match=True, boost=2.0), index.AutocompleteField('title'), index.FilterField('title'), index.RelatedFields('authors', Author.search_fields), index.FilterField('publication_date'), index.FilterField('number_of_pages'), index.RelatedFields('tags', [ index.SearchField('name'), index.FilterField('slug'), ]), index.FilterField('tags'), ] @classmethod def get_indexed_objects(cls): indexed_objects = super(Book, cls).get_indexed_objects() # Don't index books using Book class that they have a more specific type if cls is Book: indexed_objects = indexed_objects.exclude( id__in=Novel.objects.values_list('book_ptr_id', flat=True)) indexed_objects = indexed_objects.exclude( id__in=ProgrammingGuide.objects.values_list('book_ptr_id', flat=True)) # Exclude Books that have the title "Don't index me!" indexed_objects = indexed_objects.exclude(title="Don't index me!") return indexed_objects def get_indexed_instance(self): # Check if this object is a Novel or ProgrammingGuide and return the specific object novel = Novel.objects.filter(book_ptr_id=self.id).first() programming_guide = ProgrammingGuide.objects.filter( book_ptr_id=self.id).first() # Return the novel/programming guide object if there is one, otherwise return self return novel or programming_guide or self def __str__(self): return self.title
class Platform(index.Indexed, ClusterableModel): name = models.CharField(max_length=255) active = models.BooleanField(default=True) description = MarkdownField(max_length=1024) date_created = models.DateTimeField(default=timezone.now) # last_updated = models.DateField(blank=True, null=True, help_text=_("Date of last update for the ABM platform itself.")) last_modified = models.DateTimeField(auto_now=True) open_source = models.BooleanField(default=False) featured = models.BooleanField(default=False) url = models.URLField(blank=True) repository_url = models.URLField(blank=True) tags = ClusterTaggableManager(through=PlatformTag, blank=True) @staticmethod def _upload_path(instance, filename): # FIXME: base in MEDIA_ROOT? return pathlib.Path('platforms', instance.platform.name, filename) panels = [ FieldPanel('name'), FieldPanel('url'), FieldPanel('description'), FieldPanel('active'), FieldPanel('open_source'), FieldPanel('featured'), FieldPanel('tags'), ] def get_all_tags(self): return ' '.join(self.tags.all().values_list('name', flat=True)) search_fields = [ index.SearchField('name', partial_match=True), index.SearchField('description', partial_match=True), index.FilterField('active'), index.FilterField('open_source'), index.RelatedFields('tags', [ index.SearchField('name'), ]), ] def __str__(self): return self.name def __lt__(self, other): if isinstance(other, Platform): return self.name < other.name raise TypeError("Unorderable types: {0} < {1}".format( Platform, type(other)))
class Novel(Book): setting = models.CharField(max_length=255) protagonist = models.OneToOneField(Character, related_name='+', null=True, on_delete=models.SET_NULL) search_fields = Book.search_fields + [ index.SearchField('setting', partial_match=True), index.RelatedFields('characters', [ index.SearchField('name', boost=0.25), ]), index.RelatedFields('protagonist', [ index.SearchField('name', boost=0.5), index.FilterField('novel'), ]), index.FilterField('protagonist'), ]
class EventPage(Page): date_from = models.DateField("Start date", null=True) date_to = models.DateField( "End date", null=True, blank=True, help_text="Not required if event is on a single day" ) time_from = models.TimeField("Start time", null=True, blank=True) time_to = models.TimeField("End time", null=True, blank=True) audience = models.CharField(max_length=255, choices=EVENT_AUDIENCE_CHOICES) location = models.CharField(max_length=255) body = RichTextField(blank=True) cost = models.CharField(max_length=255) signup_link = models.URLField(blank=True) feed_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) categories = ParentalManyToManyField(EventCategory, blank=True) search_fields = [ index.SearchField('get_audience_display'), index.SearchField('location'), index.SearchField('body'), index.FilterField('url_path'), ] password_required_template = 'tests/event_page_password_required.html' base_form_class = EventPageForm
class ExternalVideo(ExternalContent): resource_type = "video" is_external = True # Meta fields date = DateField( "Video date", default=datetime.date.today, help_text="The date the video was published", ) speakers = StreamField( StreamBlock( [("speaker", PageChooserBlock(target_model="people.Person"))], required=False, ), blank=True, null=True, help_text= "Optional list of people associated with or starring in the video", ) duration = CharField( max_length=30, blank=True, null=True, help_text=("Optional video duration in MM:SS format e.g. “12:34”. " "Shown when the video is displayed as a card"), ) meta_panels = [ FieldPanel("date"), StreamFieldPanel("speakers"), InlinePanel("topics", heading="Topics"), FieldPanel("duration"), ] settings_panels = BasePage.settings_panels + [FieldPanel("slug")] edit_handler = TabbedInterface([ ObjectList(ExternalContent.card_panels, heading="Card"), ObjectList(meta_panels, heading="Meta"), ObjectList(settings_panels, heading="Settings", classname="settings"), ]) # Search config search_fields = BasePage.search_fields + [ # Inherit search_fields from Page # "title" is already specced in BasePage index.SearchField("description"), # Add FilterFields for things we may be filtering on (eg topics) index.FilterField("slug"), ] @property def video(self): return self def has_speaker(self, person): for speaker in self.speakers: # pylint: disable=not-an-iterable if str(speaker.value) == str(person.title): return True return False
class TranslatableBook(TranslatableMixin, models.Model, index.Indexed): author = models.ForeignKey(Author, on_delete=models.PROTECT) title = models.CharField(max_length=255) cover_image = models.ForeignKey("wagtailimages.Image", on_delete=models.SET_NULL, null=True, blank=True) search_fields = [ index.SearchField("title"), index.FilterField("title"), index.FilterField("id"), ] def __str__(self): return self.title
class NewsPage(Page): body = RichTextField() post_date = models.DateField("Post date") feed_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') search_fields = Page.search_fields + [ index.FilterField('post_date'), index.SearchField('body', partial_match=True), ] # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('post_date'), FieldPanel('body', classname="full"), InlinePanel('related_links', label="Related links"), ] promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ImageChooserPanel('feed_image'), ] # Parent page / subpage type rules parent_page_types = ['home.NewsIndexPage'] subpage_types = []
class TagCaption(index.Indexed, ClusterableModel): tags = TaggableManager('Теги', through=TagCaptionTag, blank=True) raw_content = RichTextField('Текст') @property def content(self): return richtext(self.raw_content) paneles = [FieldPanel('tags'), FieldPanel('content')] def __str__(self): return ' / '.join(self.tags.all().values_list('name', flat=True)) search_fields = [ index.SearchField('tags'), index.RelatedFields('tags', [ index.SearchField('slug'), index.FilterField('slug'), ]), ] api_fields = [ APIField('tags', serializer=serializers.TagSerializer()), APIField('content') ] class Meta: verbose_name = 'Примечание' verbose_name_plural = 'Примечания'
class DigestPage(ContentPage): date = models.DateField(default=datetime.date.today) read_next = models.ForeignKey('DigestPage', blank=True, null=True, default=get_previous_digest_page, on_delete=models.SET_NULL) content_panels = ContentPage.content_panels + [ FieldPanel('date'), InlinePanel('authors', label="Authors"), PageChooserPanel('read_next'), ] template = 'home/updates/digest_page.html' search_fields = ContentPage.search_fields + [index.FilterField('date')] @property def content_section(self): return 'about' @property def get_update_type(self): return constants.update_types['weekly-digest'] @property def get_author_office(self): return 'Press Office' @property def social_image_identifier(self): return 'weekly-digest'
class Event(Page): date = models.DateField("Event date") place = models.CharField(max_length=250) agenda = RichTextField(blank=True) notes = RichTextField(blank=True) resources = RichTextField(blank=True) attended = models.IntegerField( blank=True, null=True, help_text= "Please enter the number of people that attended, or leave blank") search_fields = Page.search_fields + [ index.SearchField('agenda', partial_match=True), index.SearchField('notes', partial_match=True), index.SearchField('resources', partial_match=True), index.FilterField('date') ] content_panels = Page.content_panels + [ FieldPanel('date'), FieldPanel('place'), FieldPanel('agenda', classname="full"), FieldPanel('notes', classname="full"), FieldPanel('resources', classname="full"), FieldPanel('attended'), ] def get_context(self, request): context = super(Event, self).get_context(request) context['today'] = date.today() return context
class LoguePage(Page): date = models.DateField("Post date") header_image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+" ) intro = models.CharField(max_length=250) body = RichTextField(blank=True) feed_image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+" ) search_fields = Page.search_fields + [ index.SearchField("intro"), index.SearchField("body"), index.FilterField("date"), ] content_panels = Page.content_panels + [ FieldPanel("date"), ImageChooserPanel("header_image"), FieldPanel("intro"), FieldPanel("body", classname="full"), ] promote_panels = [ImageChooserPanel("feed_image")]
class HomePage(Page, models.Model): # db fields h_one = models.CharField(max_length=250, default="H1") h_one_span = models.CharField(max_length=250, default="H1 Span") content = models.TextField(blank=True, null=True) # Search index configuration search_fields = Page.search_fields + [ index.SearchField('h_one'), index.SearchField('h_one_span'), index.FilterField('content'), ] # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('h_one'), FieldPanel('h_one_span'), FieldPanel('content'), ] # API configuration api_fields = [ APIField('h_one'), APIField('h_one_span'), APIField('content'), ]
class DocumentSushi(Document): (T_TEH_CARD, T_REGULATIONS, T_PROMOTIONS, T_BEFORE_OPEN, T_MENU, T_OTHER_MAKET, T_VIDEO, T_AUDIO, T_PERSONAL, T_PERSONAL_INVOICES, T_TRAINING) = range(11) STATUS_CHOICE = ( (T_TEH_CARD, "Техкарты"), (T_REGULATIONS, "Регламенты"), (T_PROMOTIONS, "Акции"), (T_BEFORE_OPEN, "Перед открытием"), (T_MENU, "Меню"), (T_OTHER_MAKET, "Другие макеты"), (T_VIDEO, "Видеоролики"), (T_AUDIO, "Аудиоролики"), (T_PERSONAL, "Личные документы"), (T_PERSONAL_INVOICES, "Личные счета"), (T_TRAINING, "Обучение"), ) doc_type = models.IntegerField(choices=STATUS_CHOICE, default=T_TEH_CARD) sub_type = models.ForeignKey(Subjects, verbose_name='тематика', on_delete=models.CASCADE, related_name='documents', null=True, blank=True) search_fields = Document.search_fields + [ index.SearchField('doc_type'), index.FilterField('doc_type'), index.FilterField('sub_type_id') ] @property def preview(self): path = '/media/icons_documents/' file_extension = self.file_extension.lower() if file_extension in ('jpg', 'svg', 'png', 'bmp'): return self.url if file_extension in ('doc', 'docx'): return f'{path}word.svg' elif file_extension in ('xls', 'xlsx'): return f'{path}excel.svg' else: return f'{path}{file_extension}.svg'
class BlogPage(Page): # title = models.CharField(max_length=128) short_description = RichTextField() description = RichTextField() content = RichTextField() date = models.DateField("Post date") image = models.ForeignKey('wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True) search_fields = Page.search_fields + [ index.SearchField('content'), index.FilterField('date'), ] content_panels = Page.content_panels + [ # FieldPanel('title'), FieldPanel('date'), FieldPanel('short_description'), FieldPanel('description'), FieldPanel('content'), ImageChooserPanel('image'), # InlinePanel('related_links', label="Related links"), ] ''' promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ImageChooserPanel('image'), ] ''' # Parent page / subpage type rules # parent_page_types = ['blog.BlogIndex'] subpage_types = [] PAGE_TEMPLATE_VAR = 'page' def get_context(self, request, *args, **kwargs): context = { self.PAGE_TEMPLATE_VAR: self, 'self': self, 'request': request, } if self.context_object_name: context[self.context_object_name] = self context['menuitems'] = Page.objects.filter(live=True, show_in_menus=True) return context def save(self, *args, **kwargs): self.slug = slugify(self.title) super().save(*args, **kwargs)
class IndexedPageRevision(index.Indexed, PageRevision): search_fields = [ index.SearchField('content_json'), index.FilterField('created_at'), ] class Meta: proxy = True
class EntryPage(Entry, TranslatablePage): # Search search_fields = TranslatablePage.search_fields + [ index.SearchField('body'), index.SearchField('excerpt'), index.FilterField('translatablepage_ptr_id') ] # Panels content_panels = getattr(Entry, 'content_panels', []) promote_panels = TranslatablePage.promote_panels + getattr(Entry, 'promote_panels', []) settings_panels = TranslatablePage.settings_panels + [ FieldPanel('date'), FieldPanel('owner'), ] + getattr(Entry, 'settings_panels', []) # Parent and child settings parent_page_types = ['puput.BlogPage'] subpage_types = [] def get_sitemap_urls(self, request=None): from .urls import get_entry_url root_url = self.get_url_parts()[1] entry_url = get_entry_url(self, self.blog_page.translatablepage_ptr, root_url) return [ { 'location': root_url + entry_url, # fall back on latest_revision_created_at if last_published_at is null # (for backwards compatibility from before last_published_at was added) 'lastmod': (self.last_published_at or self.latest_revision_created_at), } ] @property def blog_page(self): return self.get_parent().specific @property def related(self): return [related.entrypage_to for related in self.related_entrypage_from.all()] @property def has_related(self): return self.related_entrypage_from.count() > 0 def get_absolute_url(self): return self.full_url def get_context(self, request, *args, **kwargs): context = super(EntryPage, self).get_context(request, *args, **kwargs) context['blog_page'] = self.blog_page return context class Meta: verbose_name = _('Entry') verbose_name_plural = _('Entries')
def test_basic(self): cls = self.make_dummy_type([ index.SearchField("test", boost=100, partial_match=False), index.FilterField("filter_test"), ]) self.assertEqual(len(cls.get_search_fields()), 2) self.assertEqual(len(cls.get_searchable_search_fields()), 1) self.assertEqual(len(cls.get_filterable_search_fields()), 1)
class EventPage(Page): date_from = models.DateField("Start date", null=True) date_to = models.DateField( "End date", null=True, blank=True, help_text="Not required if event is on a single day" ) time_from = models.TimeField("Start time", null=True, blank=True) time_to = models.TimeField("End time", null=True, blank=True) audience = models.CharField(max_length=255, choices=EVENT_AUDIENCE_CHOICES) location = models.CharField(max_length=255) body = RichTextField(blank=True) cost = models.CharField(max_length=255) signup_link = models.URLField(blank=True) feed_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) categories = ParentalManyToManyField(EventCategory, blank=True) search_fields = [ index.SearchField('get_audience_display'), index.SearchField('location'), index.SearchField('body'), index.FilterField('url_path'), ] password_required_template = 'tests/event_page_password_required.html' base_form_class = EventPageForm content_panels = [ FieldPanel('title', classname="full title"), FieldPanel('date_from'), FieldPanel('date_to'), FieldPanel('time_from'), FieldPanel('time_to'), FieldPanel('location'), FieldPanel('audience'), FieldPanel('cost'), FieldPanel('signup_link'), InlinePanel('carousel_items', label="Carousel items"), FieldPanel('body', classname="full"), InlinePanel('speakers', label="Speakers", heading="Speaker lineup"), InlinePanel('related_links', label="Related links"), FieldPanel('categories'), # InlinePanel related model uses `pk` not `id` InlinePanel('head_counts', label='Head Counts'), ] promote_panels = [ MultiFieldPanel(COMMON_PANELS, "Common page configuration"), ImageChooserPanel('feed_image'), ]