示例#1
0
class AccordionEntry(Orderable):
    accordion_page = ParentalKey(to=AccordionPage,
                                 on_delete=models.CASCADE,
                                 related_name='entry')

    header_de = models.CharField(max_length=128)
    header_it = models.CharField(max_length=128)
    body_de = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    body_it = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    header = TranslatedField(
        'header_de',
        'header_it',
    )
    body = TranslatedField(
        'body_de',
        'body_it',
    )
    show_in_menus_default = True

    def __str__(self) -> str:
        return self.header
示例#2
0
class StaffListing(BasePage):
    subpage_types = ["Employee"]
    max_count_per_parent = 1

    heading = models.CharField("Überschrift",
                               max_length=50,
                               default="Mitarbeiter*innen")
    intro = RichTextField("Intro", blank=True)
    image = models.ForeignKey(
        Image,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="+",
        verbose_name="Bild",
    )
    outro = RichTextField("Outro", blank=True)

    departments = ParentalManyToManyField(
        Department,
        blank=True,
        related_name="+",
        verbose_name="Anzuzeigende Abteilungen",
        help_text=
        "Es werden nur Mitarbeiter:innen aus diesen Abteilungen angezeigt",
    )

    content_panels = [
        FieldPanel("title"),
        FieldPanel("heading"),
        FieldPanel("intro"),
        ImageChooserPanel("image"),
        HelpPanel(
            "An dieser Stelle kommen die Mitarbeiter*innen, die als Unterseiten angelegt sind.",
            heading="Mitarbeiter*innen",
        ),
        FieldPanel("departments", widget=forms.CheckboxSelectMultiple),
        FieldPanel("outro"),
    ]

    class Meta:
        verbose_name = "Auflistung von Mitarbeiter*innen"
        verbose_name_plural = "Auflistungen von Mitarbeiter*innen"

    def get_context(self, request):
        context = super().get_context(request)
        context["people"] = []
        for department in self.departments.all():
            people = Employee.objects.filter(
                departments=department).order_by("title")
            if people:
                context["people"].append({
                    "department": department,
                    "people": people
                })
        return context
示例#3
0
文件: models.py 项目: yemilab/cms
class StandardEquipmentPage(Page):
    DATEFMT = [
        ('Y', 'Year'),
        ('YM', 'Year-Month'),
        ('YMD', 'Year-Month-Date'),
    ]
    cover_photo = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    manufacturer = models.CharField(max_length=256)
    manufacture_date_fmt = models.CharField(max_length=8, choices=DATEFMT, default='YMD')
    manufacture_date = models.DateField()
    model = models.CharField(max_length=256)
    location = models.CharField(max_length=256)
    manager = models.ForeignKey(
        'home.Person',
        null=True,
        blank=True,
        related_name='+',
        on_delete=models.PROTECT
    )
    related_link = models.URLField(blank=True, null=True)
    purpose = RichTextField(blank=True, null=True)
    spec = RichTextField("Specification and performance", blank=True, null=True)
    extra = RichTextField(blank=True, null=True)

    content_panels = Page.content_panels + [
        ImageChooserPanel('cover_photo'),
        FieldPanel('manufacturer'),
        FieldPanel('manufacture_date_fmt'),
        FieldPanel('manufacture_date'),
        FieldPanel('model'),
        FieldPanel('location'),
        FieldPanel('manager'),
        FieldPanel('purpose', classname='full'),
        FieldPanel('spec', classname='full'),
        InlinePanel(
            'equipment_photo_relationship',
            label="Photo(s)",
            panels=None),
        FieldPanel('related_link'),
        FieldPanel('extra', classname='full'),
    ]

    parent_page_types = ['EquipmentIndexPage']
    subpage_types = []

    def photos(self):
        return [ n.photo for n in self.equipment_photo_relationship.all() ]
示例#4
0
class Product(models.Model):
    """
        A product has a mandatory name, supplier, price, quantity, quantity_per_unit and a unit field.
        Optionally, an image can be assigned to it, along with a descriptive text provided by the supplier
        Join tables include ProductLabel, ProductType and ProductAllergen
    """
    name = models.CharField(max_length=200,
                            null=False,
                            blank=False,
                            default=None)
    slug = AutoSlugField(populate_from=["name", "supplier"], )
    supplier = models.ForeignKey(SupplierUser,
                                 on_delete=models.CASCADE,
                                 null=False,
                                 blank=False,
                                 default=None)
    price = models.FloatField(default=9999.99)
    quantity = models.PositiveIntegerField(default=0)
    quantity_per_unit = models.FloatField(default=1)
    unit = models.ForeignKey(ProductUnit,
                             blank=False,
                             null=True,
                             on_delete=models.SET_NULL)
    type = models.ForeignKey(ProductType,
                             blank=False,
                             null=True,
                             on_delete=models.SET_NULL)

    labels = models.ManyToManyField(ProductLabel, blank=True)
    allergens = models.ManyToManyField(ProductAllergen, blank=True)

    description = RichTextField(null=True,
                                blank=True,
                                default="Fresh, local, fair price.")
    farmers_advice = RichTextField(null=True, blank=True)
    image = models.ImageField(default=None)

    def get_absolute_url(self):
        return reverse("store:product", kwargs={'slug': self.slug})

    def get_add_to_cart_url(self):
        return reverse("store:add_to_cart", kwargs={'slug': self.slug})

    def get_add_to_cart_url_next(self):
        return reverse("store:add_to_cart_next", kwargs={'slug': self.slug})

    class Meta:
        verbose_name = "Product"
        verbose_name_plural = "Products"

    def __str__(self):
        return str(self.pk) + ' ' + self.name
示例#5
0
class HomePage(Page):
    # title is used for title in German
    title_it = models.CharField(max_length=256, blank=True)
    # 1st body bilingual
    body_top_de = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    body_top_it = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    # 2nd body bilingual
    body_bottom_de = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    body_bottom_it = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    content_panels = [
        FieldRowPanel([
            FieldPanel('title'),
            FieldPanel('title_it'),
        ]),
        FieldRowPanel([
            FieldPanel('body_top_de'),
            FieldPanel('body_top_it'),
        ]),
        InlinePanel('home_page_images', label="Images"),
        FieldRowPanel([
            FieldPanel('body_bottom_de'),
            FieldPanel('body_bottom_it'),
        ]),
    ]
    translated_title = TranslatedField(
        'title',
        'title_it',
    )
    body_top = TranslatedField(
        'body_top_de',
        'body_top_it',
    )
    body_bottom = TranslatedField(
        'body_bottom_de',
        'body_bottom_it',
    )
    show_in_menus_default = True
示例#6
0
class AskPage(Page):
    max_count = 1
    parental_page_type = ['ConsIndexPage', ]
    # поле для ввода текста
    raw_content = RichTextField('Содержание', blank=True)
    
    @property  # тут получаем текст с валидными тегами
    def content(self):
        return richtext(self.raw_content)

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    
    content_panels = Page.content_panels + [
        FieldPanel('raw_content')
    ]

    api_fields = [
        APIField('breadcrumbs'),
        APIField('content'),
    ]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Задать вопрос'
示例#7
0
class SeminarPage(Page):
    date = models.DateTimeField()
    speaker = models.CharField(max_length=250)
    speaker_affiliation = models.CharField(max_length=250, blank=True)
    place = models.CharField(max_length=250)
    abstract = RichTextField()
    extra = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('speaker'),
        FieldPanel('speaker_affiliation'),
        FieldPanel('place'),
        FieldPanel('abstract', classname="full"),
        FieldPanel('extra', classname="full"),
    ]

    parent_page_types = ['SeminarsIndexPage']
    subpage_types = []
示例#8
0
class PostPage(Page):
    body = RichTextField(blank=True)
    categories = ParentalManyToManyField('blog.BlogCategory', blank=True)
    tags = ClusterTaggableManager(through='blog.BlogPageTag', blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        FieldPanel('tags')
    ]
示例#9
0
class HomePage(Page):
    """Домашняя страница"""

    max_count = 1
    
    text = RichTextField(blank=True, verbose_name='Текст')
    text_sign = RichTextField(max_length=250, blank=True, verbose_name='Подпись')
    about_text = StreamField([('about_text', AboutTextBlock())], blank=True)
    section_cards= StreamField([('section_card', SectionLinkBlock())], blank=True)
    ads = StreamField([('ad', AdBlock())], blank=True)
    banner = models.ForeignKey(
        'wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True
    )

    content_panels = Page.content_panels + [
        StreamFieldPanel('section_cards', heading='Карточки разделов'),
        StreamFieldPanel('ads', heading='Объявления'),
        StreamFieldPanel('about_text', heading='О сайте'),
        ImageChooserPanel('banner', heading='Иллюстрация')
    ]

    api_fields = [
        APIField("section_cards"),
        APIField("ads"),
        APIField("about_text"),
        APIField("text"),
        APIField("text_sign"),
        APIField("banner", serializer=ImageRenditionField(BANNER_SIZE))
    ]

    def get_admin_display_title(self):
        return 'Главная'

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]


    class Meta:
        verbose_name = 'Главная страница'
示例#10
0
class ConsIndexPage(Page):
    """Главная страница консультаций"""
    max_count = 1
    subpage_types = ['cons.ConsPage', 'cons.FAQIndexPage', 'cons.AskPage']
    note = RichTextField(blank=True, verbose_name='Примечание')
    ads = StreamField([
        ('ad', blocks.RichTextBlock(help_text='Объявление', label='Объявление'))
    ], blank=True)
    last_consults_note = RichTextField(blank=True, verbose_name='О режиме публикации')
    banner = models.ForeignKey(
        'wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True
    )

    @property
    def tags_menu(self):
        return cons_tags_menu


    api_fields = [
        APIField("note"),
        APIField("ads"),
        APIField("last_consults_note"),
        APIField("banner", serializer=ImageRenditionField(BANNER_SIZE)),
        APIField("tags_menu")
    ]

    content_panels = Page.content_panels + [
        FieldPanel('note', heading='Примечание для «Задать вопрос»'),
        StreamFieldPanel('ads', heading='Объявления'),
        FieldPanel('last_consults_note', heading='О режиме публикации'),
        ImageChooserPanel('banner', heading='Иллюстрация')
    ]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Страница консультаций'
示例#11
0
class AccordionPage(Page):
    # title is used for title in German
    title_it = models.CharField(max_length=256, blank=True)
    # 1st body bilingual
    body_top_de = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])
    body_top_it = RichTextField(
        blank=True,
        default="",
        features=['h2', 'h3', 'bold', 'italic', 'ol', 'ul', 'hr', 'link'])

    image = models.ForeignKey(
        'wagtailimages.Image',
        on_delete=models.SET_NULL,
        related_name='+',
        null=True,
        blank=True,
    )
    content_panels = [
        FieldRowPanel([
            FieldPanel('title'),
            FieldPanel('title_it'),
        ]),
        FieldRowPanel([
            FieldPanel('body_top_de'),
            FieldPanel('body_top_it'),
        ]),
        ImageChooserPanel('image'),
        InlinePanel('entry', label='accordion entry'),
    ]
    translated_title = TranslatedField(
        'title',
        'title_it',
    )
    body_top = TranslatedField(
        'body_top_de',
        'body_top_it',
    )
示例#12
0
class HomePage(Page):
    """Главная страница."""

    body = RichTextField(blank=True)
    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full")
    ]

    def get_context(self, request, *args, **kwargs):
        context = super(HomePage, self).get_context(request, *args, **kwargs)
        # context['posts'] = self.posts
        context['blog_page'] = self

        context['menuitems'] = self.get_children().filter(live=True,
                                                          show_in_menus=True)

        return context
示例#13
0
文件: models.py 项目: yemilab/cms
class TweetPage(Page):
    body = RichTextField()
    date_published = models.DateField(
        "Date article published", blank=True, null=True
    )

    content_panels = Page.content_panels + [
        FieldPanel('body'),
        FieldPanel('date_published'),
    ]

    api_fields = [
        APIField('body'),
        APIField('date_published'),
    ]

    parent_page_types = ['TweetIndexPage']
    subpage_types = []
示例#14
0
class Beta(Page):

    templates = 'lesson/beta.html'
    lesson_name = models.CharField(max_length=150, null=False, blank=False)

    lesson_summary = RichTextField(
        max_length=500,
        null=False,
        blank=False,
        help_text=
        "Enter a description of this lesson. Use bullet points rather than paragraphs to separate out the key ojectives. You can use up to 500 characters.",
        features=[
            'ul',
            'bold',
            'italic',
        ])

    presentation_link = models.URLField(max_length=200, blank=True, null=True)

    content = StreamField([
        ("test", blocks.LessonContentBlock()),
    ],
                          null=True,
                          blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("lesson_name"),
        FieldPanel("lesson_summary"),
        FieldPanel("presentation_link"),
        StreamFieldPanel("content"),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['subject_name'] = self.get_ancestors(
            inclusive=True).not_type(HomePage).exclude(title__contains="Root")

        context['key_stage'] = self.get_parent()
        context['siblings'] = self.get_siblings()

        return context
class ContentSection(Page, SectionBase):
    """A content section with an WYSIWYG Richtext editro"""
    content_richtext = RichTextField()

    # basic tab panels
    basic_panels = Page.content_panels + [
        SectionBase.section_content_panels,
        RichTextFieldPanel(
            'content_richtext',
            heading='Richtext',
        ),
        SectionBase.section_layout_panels,
        SectionBase.section_design_panels,
    ]

    # Register Tabs
    edit_handler = TabbedInterface([
        ObjectList(basic_panels, heading="Basic"),
    ])

    # Page settings
    template = 'sections/content_section_preview.html'
    parent_page_types = ['home.HomePage']
    subpage_types = []

    # Overring methods
    def set_url_path(self, parent):
        """
        Populate the url_path field based on this page's slug and the specified parent page.
        (We pass a parent in here, rather than retrieving it via get_parent, so that we can give
        new unsaved pages a meaningful URL when previewing them; at that point the page has not
        been assigned a position in the tree, as far as treebeard is concerned.
        """
        if parent:
            self.url_path = ''
        else:
            # a page without a parent is the tree root, which always has a url_path of '/'
            self.url_path = '/'

        return self.url_path
示例#16
0
class FAQPage(Page):
    parent_page_types = ['FAQIndexPage',]
    subpage_types = []
    number = models.PositiveIntegerField(verbose_name='Номер', unique=True, default=get_default_faq_number)
    tags = ClusterTaggableManager(through=FAQPageTag, blank=True, verbose_name='Теги')
    # поле для ввода текста
    raw_content = RichTextField('Содержание', blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('number'),
        FieldPanel('tags'),
        FieldPanel('raw_content'),
    ]


    @property  # тут получаем текст с валидными тегами
    def text(self):
        return richtext(self.raw_content)

    @property 
    def tag_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    search_fields = Page.search_fields + [
        index.SearchField('number'),
        index.SearchField('text'),
        index.FilterField('tags'),
        index.SearchField('tag_slugs'),
        index.FilterField('number')
    ]

    api_fields = [
    APIField('section_title'),
    APIField('section_url'),
    APIField('breadcrumbs'),
    APIField('number'),
    APIField('tags', serializer=serializers.TagSerializer()),
    APIField('text'),
    APIField('number'),
    APIField('clean_preview'),
    ]
    
    def clean(self):
        super().clean()
        if self.slug == 'default-blank-slug':
            slug = f'f-{str(self.number)}'
            if len(self.title) > 30:
                self.slug = slug + '-' + slugify(self.title[:30])
            else:
                self.slug = slug + '-' + slugify(self.title)

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]
        
    class Meta:
        verbose_name = 'Частый вопрос'
示例#17
0
class ExternalProgramWebsite(models.Model):
    """
    Section on the Program Page linking back to the externally hosted program website and describing what learners can
    expect to find there.
    For example, for the program "Masters in Potions Ingredients Science", this section may include a link to the
    "hogwarts.edu" website which would be hosted and managed by Hogwarts.  The description would explain what learners
    can expect to find at "hogwarts.edu".  For example, "Chat with a professor", "Add or drop a course", "Contact St.
    Mungo's Poison Control Hotline".

    .. no_pii:
    """
    DEFAULT_DESCRIPTION = re.sub(
        r'>\s+<',
        r'><',
        """
        <p>Go to your program's portal to:</p>
        <ul>
            <li>Add or drop courses</li>
            <li>Finance Department</li>
            <li>Contact an advisor</li>
            <li>Get your grade</li>
            <li>Program wide discussions</li>
            <li>and more</li>
        </ul>
        """
    ).strip()

    display = models.BooleanField(
        blank=False,
        null=False,
        default=True,
        verbose_name="Display This Section",
    )
    header = models.CharField(
        max_length=128,
        verbose_name='Header',
        blank=False,
        null=False,
        default='Manage Your Degree'
    )
    description = RichTextField(
        max_length=512,
        verbose_name='description',
        blank=False,
        null=False,
        features=('bold', 'italic', 'ol', 'ul'),
        default=DEFAULT_DESCRIPTION,
    )
    link_display_text = models.CharField(
        blank=False,
        null=False,
        max_length=128,
        verbose_name="Display Text"
    )
    link_url = models.URLField(
        blank=False,
        null=False,
        verbose_name="URL",
    )

    page = ParentalKey(ProgramPage, on_delete=models.CASCADE, related_name='external_program_website', unique=True)

    panels = [
        FieldPanel('display'),
        FieldPanel('header'),
        RichTextFieldPanel('description'),
        MultiFieldPanel(
            [
                FieldPanel('link_display_text'),
                FieldPanel('link_url'),
            ],
            heading='Link to Homepage',
            classname='collapsible',
        )
    ]
示例#18
0
class LmlPage(Page):
    body = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
    ]
示例#19
0
class MoviePage(Page):
    """Movie Page"""
    template = "movie/movie_page.html"

    video = models.ForeignKey("video.Video",
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name="+")
    sub_title = models.CharField(blank=False, null=False, max_length=255)
    hero = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text="The hero image is used in the page header.")
    hover_thumbnail = models.ForeignKey('wagtailimages.Image',
                                        null=True,
                                        blank=True,
                                        on_delete=models.SET_NULL,
                                        related_name="+")
    year = models.PositiveIntegerField(null=False, blank=False)
    producer = models.CharField(blank=True, null=True, max_length=255)
    description = RichTextField(
        features=['h3', 'h4', 'ol', 'ul', 'bold', 'italic', 'link'],
        null=True,
        blank=True)

    api_fields = [
        APIField('sub_title'),
        APIField('hero', serializer=ImageRenditionField('fill-1920x780')),
        APIField('video', serializer=VideoSerializer('fill-1024x1024 ')),
        APIField('hover_thumbnail',
                 serializer=ImageRenditionField('fill-1024x1024 ')),
        APIField('year'),
        APIField('producer'),
        APIField('description'),
    ]

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            VideoChooserPanel('video'),
        ], heading="Video"),
        MultiFieldPanel([
            FieldPanel('sub_title'),
            ImageChooserPanel('hero'),
            ImageChooserPanel('hover_thumbnail'),
        ],
                        heading="Header"),
        MultiFieldPanel([
            FieldPanel('producer'),
            FieldPanel('year'),
            FieldPanel('description'),
        ],
                        heading="Information"),
    ]

    parent_page_types = ['movie.MoviesIndexPage']
    subpage_types = []

    def __str__(self):
        return self.title
示例#20
0
class BlogPage(Page):
    parent_page_types = ["blogs.BlogListingsPage"]
    subpage_types = []
    template = "blogs/blog_page.html"

    author = models.CharField(
        max_length=150,
        help_text = "Här skriver du in namnet på författaren/författarna.",
        blank=False,
        null=True
    )

    description = models.TextField(
        max_length=300,
        blank=True,
        null=True,
        help_text="En frivillig kort beskrivning om vad ditt inlägg handlar om."
    )

    page_image = models.ForeignKey(
        'wagtailimages.Image',
        related_name="+",
        null=True,
        blank=True,
        help_text="En frivillig bakgrundsbild för sidan. Om ingen bild väljs så får inlägget automatiskt en standardbild.",
        on_delete=models.SET_NULL
    )

    presentation_image = models.ForeignKey(
        'wagtailimages.Image',
        related_name="+",
        null=True,
        blank=True,
        help_text="En frivillig presentationsbild för ditt inlägg. Om ingen bild väljs så får inlägget automatiskt en standardbild.",
        on_delete=models.SET_NULL
    )

    # start_text = models.TextField(
    #     blank=False,
    #     null=True,
    #     help_text="Här kan du skriva ett längre stycke text, som kommer hamna bredvid din presentationsbild. Det här texten är tänkt att vara 'starttexten' på ditt inlägg.",
    # )

    start_text = RichTextField(help_text="Här kan du skriva ett längre stycke text, som kommer hamna bredvid din presentationsbild. Det här texten är tänkt att vara 'starttexten' på ditt inlägg, och bör, för utseendets skull, vara max 6 rader.")

    published = models.DateField(
        blank=True,
        null=False,
        help_text="Här skriver jag inget för jag lägger inte in det i FieldPanel ens",
        default=datetime.date.today
    )

    body = StreamField([
        ("title", blocks.TitleBlock()),
        ("gallery", blocks.GalleryBlock()),
        ("richText", wagtail_blocks.RichTextBlock()),
        ("imageAndText", blocks.ImageAndText())
    ], null=True, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("author"),
        FieldPanel("description"),
        ImageChooserPanel("page_image"),
        ImageChooserPanel("presentation_image"),
        FieldPanel("start_text"),
        StreamFieldPanel("body"),
    ]
示例#21
0
class GalleryPage(Page):
    body = RichTextField(blank=True,
                         help_text=_('Body of text on page'),
                         verbose_name=_('Body'))
    """Optional body of text that is shown on a specifc gallery page"""

    description = models.TextField(blank=True,
                                   null=True,
                                   help_text=_('Short description of gallery'),
                                   verbose_name=_('Description'))
    """Optional short description of the gallery used when showing cards etc."""

    categories = models.ManyToManyField(
        'wagtail_gallery.Category',
        through='wagtail_gallery.CategoryGalleryPage',
        blank=True,
        help_text=_('Categories relevant to gallery'),
        verbose_name=_('Categories'))
    """Categories to which a particular gallery belongs"""

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
        FieldPanel('description'),
        MultiFieldPanel(
            [InlinePanel("gallery_categories", label=_("Categories"))]),
        InlinePanel(
            'gallery_image',
            label=_("Gallery image"),
            panels=[FieldPanel('description'),
                    ImageChooserPanel('image')])
    ]

    show_in_menus = False
    subpage_types = []
    parent_page_types = ["wagtail_gallery.GalleryParentPage"]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
        index.SearchField('description'),
        index.RelatedFields('categories', [
            index.SearchField('name'),
            index.SearchField('description'),
        ])
    ]

    class Meta:
        verbose_name = _("Gallery")

    def get_context(self, request: django.http.HttpRequest, *args,
                    **kwargs: dict):
        """
        Gets the context for a specific gallery page

        :param request: Django HttpRequest
        :param args: Request args
        :param kwargs: Request kwargs
        :return: Context variable
        """
        context = super(GalleryPage, self).get_context(request)

        context['archives'] = self.get_archives()

        return context

    def get_archives(self) -> list:
        """
        Gets the archives for the gallery

        :return: List of dictionaries of the form: [{'date': <GalleryPage Queryset>}]
        """
        archives = list(GalleryPage.objects.live().dates('first_published_at',
                                                         'month',
                                                         order='DESC'))
        archives = [{'date': archive} for archive in archives]
        return archives

    @property
    def get_categories(self) -> models.QuerySet:
        """
        Gets the categories available to all galleries

        :return: Queryset containing Category objects
        """
        return Category.objects.all()

    @property
    def get_gallery_base_url(self) -> str:
        """
        Gets the url of the root gallery page to which this gallery is attached

        :return: URL string
        """
        return self.get_parent().url
示例#22
0
class GalleryParentPage(RoutablePageMixin, Page):
    """
    Root page to which all galleries are attached
    """

    body = RichTextField(blank=True,
                         help_text=_('Text to appear on gallery root page'),
                         verbose_name=_('Body'))
    """ Text that accompanies that appears on root gallery page"""

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
    ]

    show_in_menus = True
    subpage_types = ['wagtail_gallery.GalleryPage']

    search_fields = Page.search_fields + [index.SearchField('body')]

    class Meta:
        verbose_name = _("Gallery Root Page")

    def get_context(self, request: django.http.HttpRequest, *args,
                    **kwargs: dict):
        """
        Overrides get_context of Page model and adds the archives and galleries to the context

        :param request: Django HttpRequest
        :param args: Request args
        :param kwargs: Request kwargs
        :return: Django context
        """
        context = super(GalleryParentPage, self).get_context(request)

        context['archives'] = self.get_archives()
        context['galleries'] = self.get_pagination(request, kwargs)

        return context

    def get_pagination(self, request: django.http.HttpRequest,
                       kwargs) -> django.core.paginator.Paginator:
        """
        Get pagination for the galleries parent page

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: Pagination object
        """
        if ('year' in kwargs) and ('month' in kwargs):
            galleries = GalleryPage.objects.live().filter(
                first_published_at__year=kwargs['year'],
                first_published_at__month=kwargs['month']).order_by(
                    '-first_published_at')
        elif 'year' in kwargs:
            galleries = GalleryPage.objects.live().filter(
                first_published_at__year=kwargs['year']).order_by(
                    '-first_published_at')
        else:
            galleries = self.get_children().live().order_by(
                '-first_published_at')
        paginator = Paginator(galleries, 10)  # Show 10 resources per page

        page = request.GET.get('page')
        try:
            galleries = paginator.page(page)
        except PageNotAnInteger:
            # If page is not an integer, deliver first page.
            galleries = paginator.page(1)
        except EmptyPage:
            # If page is out of range (e.g. 9999), deliver last page of results.
            galleries = paginator.page(paginator.num_pages)

        return galleries

    def get_pagination_category(self, request: django.http.HttpRequest,
                                kwargs) -> django.core.paginator.Paginator:
        """
        Get pagination for the galleries parent page, but filtered by category

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: Pagination object
        """
        if ('year' in kwargs) and ('month' in kwargs):
            galleries = GalleryPage.objects.live().filter(
                categories__name__icontains=kwargs['category'])
            galleries = galleries.filter(
                first_published_at__year=kwargs['year'],
                first_published_at__month=kwargs['month']).order_by(
                    '-first_published_at')
        elif 'year' in kwargs:
            galleries = GalleryPage.objects.live().filter(
                categories__name__icontains=kwargs['category'])
            galleries = galleries.filter(
                first_published_at__year=kwargs['year']).order_by(
                    '-first_published_at')
        else:
            galleries = GalleryPage.objects.live().filter(
                categories__name__icontains=kwargs['category'])
            galleries = galleries.order_by('-first_published_at')
        paginator = Paginator(galleries, 10)  # Show 10 resources per page

        page = request.GET.get('page')
        try:
            galleries = paginator.page(page)
        except PageNotAnInteger:
            # If page is not an integer, deliver first page.
            galleries = paginator.page(1)
        except EmptyPage:
            # If page is out of range (e.g. 9999), deliver last page of results.
            galleries = paginator.page(paginator.num_pages)

        return galleries

    @property
    def get_galleries(self) -> models.QuerySet:
        """
        Gets the galleries that are the children of a specific parent page

        :return: Queryset containing Gallery objects
        """
        galleries = GalleryParentPage.get_children().live()
        return galleries

    @property
    def get_categories(self) -> models.QuerySet:
        """
        Gets the categories available

        :return: Queryset consisting of gallery objects
        """
        return Category.objects.all()

    @property
    def get_gallery_base_url(self) -> str:
        """
        URL of the base gallery parent page

        :return: URL string
        """
        return self.url

    def get_archives(self) -> list:
        """
        Gets the archives of the gallery page objects

        :return: List of dictionaries containing [{'date': <GalleryPage object>]}
        """
        archives = list(GalleryPage.objects.live().dates('first_published_at',
                                                         'month',
                                                         order='DESC'))
        archives = [{'date': archive} for archive in archives]
        return archives

    def get_archives_category(self, kwargs: dict) -> list:
        """
       Gets the archives of the gallery page objects, but filtered for a specific category

       :return: List of dictionaries containing [{'date': <GalleryPage object>]}
       """
        archives = GalleryPage.objects.live().filter(
            categories__name__icontains=kwargs['category'])
        archives = list(
            archives.dates('first_published_at', 'month', order='DESC'))
        archives = [{'date': archive} for archive in archives]
        return archives

    @route(r"^(?P<year>(?:19|20)\d\d)/(?P<month>1[012]|0[1-9])/$")
    def archiveMonth(self, request: django.http.HttpRequest,
                     **kwargs: dict) -> django.http.HttpResponse:
        """
        Route that returns archive page for a given year and month that contains said year and months gallery
        pages

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: HttpResponse page that shows said archives
        """
        return render(
            request, "wagtail_gallery/gallery_parent_page.html", {
                'self': self,
                'page': self,
                'galleries': self.get_pagination(request, kwargs),
                'archives': self.get_archives()
            })

    @route(r"^(?P<year>(?:19|20)\d\d)/$")
    def archiveYear(self, request: django.http.HttpRequest,
                    **kwargs: dict) -> django.http.HttpResponse:
        """
        Route that returns archive page for a given year that contains said year and months
        gallery pages

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return:  HttpResponse page that shows said archives
        """
        return render(
            request, "wagtail_gallery/gallery_parent_page.html", {
                'self': self,
                'page': self,
                'galleries': self.get_pagination(request, kwargs),
                'archives': self.get_archives()
            })

    @route(r"^category/(?P<category>[\w\-]+)/$")
    def archive(self, request: django.http.HttpRequest,
                **kwargs: dict) -> django.http.HttpResponse:
        """
        Routing for a particular category

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: HttpResponse
        """
        return render(
            request, "wagtail_gallery/gallery_parent_page.html", {
                'self': self,
                'page': self,
                'galleries': self.get_pagination_category(request, kwargs),
                'archives': self.get_archives_category(kwargs)
            })

    @route(
        r"^category/(?P<category>[\w\-]+)/(?P<year>(?:19|20)\d\d)/(?P<month>1[012]|0[1-9])/$"
    )
    def archiveCategoryMonth(self, request: django.http.HttpRequest,
                             **kwargs: dict) -> django.http.HttpResponse:
        """
        Routing for a particular category filtered for a particular year and month

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: HttpResponse
        """
        return render(
            request, "wagtail_gallery/gallery_parent_page.html", {
                'self': self,
                'page': self,
                'galleries': self.get_pagination_category(request, kwargs),
                'archives': self.get_archives_category(kwargs)
            })

    @route(r"^category/(?P<category>[\w\-]+)/(?P<year>(?:19|20)\d\d)/$")
    def archiveCategoryYear(self, request: django.http.HttpRequest,
                            **kwargs: dict) -> django.http.HttpResponse:
        """
        Routing for a particular category filtered only by year

        :param request: Django HttpRequest
        :param kwargs: Request kwargs
        :return: HttpResponse
        """
        return render(
            request, "wagtail_gallery/gallery_parent_page.html", {
                'self': self,
                'page': self,
                'galleries': self.get_pagination_category(request, kwargs),
                'archives': self.get_archives_category(kwargs)
            })
示例#23
0
文件: models.py 项目: janun/janunde
class Banner(ClusterableModel):
    """Website Banner

    TODO:
     * Field where is shown (top vs bottom)
    """

    active = models.BooleanField("aktiviert", default=True)
    text = RichTextField("Text", features=["bold", "italic", "link"])

    image = models.ForeignKey(
        "core.AttributedImage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="Bild",
        help_text="Kleines Bild, das links angezeigt werden kann. Icons o.ä.",
    )

    color = models.CharField(
        "Farbe",
        max_length=16,
        choices=[
            ("white", "Weiß"),
            ("green", "Grün"),
            ("blue", "Blau"),
            ("red", "Rot"),
            ("purple", "Lila"),
            ("black", "Schwarz"),
        ],
        default="white",
        help_text="Hintergrundfarbe des Banners",
    )

    button_text = models.CharField(
        "Button-Text",
        max_length=255,
        null=True,
        blank=True,
        help_text="Wird auf mobil nicht angezeigt",
    )
    button_link = models.URLField("Button-Link",
                                  max_length=255,
                                  null=True,
                                  blank=True)

    where = models.CharField(
        "Wo",
        max_length=100,
        choices=[
            ("everywhere", "Alle Seiten"),
            ("homepage", "Nur Startseite"),
            ("not_homepage", "Alle außer Startseite"),
        ],
        default="everywhere",
        help_text="Auf welchen Seiten soll das Banner angezeigt werden?",
    )

    panels = [
        FieldPanel("active"),
        FieldPanel("where"),
        FieldPanel("color"),
        ImageChooserPanel("image"),
        FieldPanel("text"),
        FieldRowPanel([
            FieldPanel("button_text"),
            FieldPanel("button_link"),
        ]),
    ]

    @property
    def bg_color(self):
        COLORS = {
            "white": "bg-white",
            "green": "bg-green-600",
            "blue": "bg-blue-500",
            "red": "bg-red-600",
            "purple": "bg-purple",
            "black": "bg-gray-900",
        }
        return COLORS[self.color]

    @property
    def text_color(self):
        if self.color == "white":
            return "text-gray-900"
        return "text-white"

    @classmethod
    def get_by_request(cls, request):
        qs = cls.objects.filter(active=True)
        if request.path == "/":
            return qs.exclude(where="not_homepage")
        if request.path != "/":
            return qs.exclude(where="homepage")