Cms django шаблоны: Как работать с шаблонами | Документация Django CMS 3.9

Не работает {% page_url %} в django cms

2 декабря 2016 г. 21:46

Теги:

Django,

Django-cms

Когда перестаёт работать какой-нибудь django-cms тег (например {% page_url %}), проверьте передали ли вы context при рендере шаблона. Эту ошибку я описывал в статье You must enable the ‘sekizai.context_processors.sekizai’. В ней эта ошибка более подробно расписана, и, чтобы не повторяться, я просто приведу пример правильного использования context для того, чтобы заработал рендер шаблона:

@register.inclusion_tag('quote.html', takes_context=True)
def get_quote(context):
    context['quote'] = Quote.objects.last()
    return context

И сам шаблончик quote.html:

{% load cms_tags %}
<blockquote>
    <p>{{ quote.text|linebreaksbr }}</p>
    {% page_url 'quote-authors' as quote_authors_url %}
    {% if quote_authors_url %}<a href="{{ quote_authors_url }}">{{ quote. author }}</a>
    {% else %}<p>{{ quote.author }}</p>{% endif %}
</blockquote>

Оцените статью

0 из 5 (всего 0 оценок)

Символы на картинке

Отмеченные звёздочкой поля ( * ) являются обязательными для заполнения.

Спасибо за ваш отзыв!

После нажатия кнопки «Отправить» ваше сообщение будет доставлено мне на почту.

Автор статьи

Артём Мальцев

Веб-разработчик, владеющий знаниями языка программирования Python, фреймворка Django, системы управления содержимым сайта Django CMS, платформы для создания интернет-магазина Django Shop и многих различных приложений, использующих эти технологии.

Права на использование материала, расположенного на этой странице https://vivazzi.pro/ru/it/page-url-does-not-work/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Артём Мальцев
Ссылка на статью: <a href="https://vivazzi.pro/ru/it/page-url-does-not-work/">https://vivazzi.pro/ru/it/page-url-does-not-work/</a>

Больше: Правила использования сайта

Предыдущая статьяYou must enable the ‘sekizai.context_processors.sekizai’

Следующая статьяПолучить id из url python

  • Убрать расстояние между inline-block в Django
  • Cache для классов, основанных на представлении
  • Совместимость версий библиотек
  • Свои шаблоны для обработки ошибок 403, 404 в django
  • ‘PageSmartLinkWidget’ object has no attribute ‘language’

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

Книга предназначается для широкого круга читателей и, по мнению автора, будет полезна специалистам отдела закупок и логистики, категорийным и финансовым менеджерам, менеджерам по продажам, аналитикам, руководителям и директорам, в компетенции которых принятие решений по управлению ассортиментом.

Узнать подробнее

Запускаем простой блог на Wagtail CMS (Django) — часть 2

С момента написания первой части про Wagtail CMS уже вышла версия 1.6.3 — самое время продолжить наш путь по созданию простого блога.

В первой части мы создали только первый пост в блоге. Для полноценной работы нашего сайта этого мало, так что пора сделать полноценный подраздел, вывод на главную трех последних постов, навигацию, хлебные крошки и слайдер.

В прошлой части мы создали базовую страницу блога, в которой по умолчанию есть главное изображение ‘main_image’.

В Wagtail логика работы с изображениями довольно простая. За управление изображениями в models.py отвечает строка:

from wagtail.wagtailimages.edit_handlers import ImageChooserPanel


В админ.панели добавление изображения отображается так:

Добавление изображения на страницу определяется следующим блоком:

class BlogPage(Page):
     main_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
        )
     content_panels = Page.content_panels + [
        FieldPanel('date'),
        ImageChooserPanel('main_image'), #добавляет пункт выбора изображения в админ.панели страницы
        FieldPanel('intro'),
        FieldPanel('body'),
        ]


На страницу изображение выводиться благодаря коду в blog/templates/blog/blog_page.html:

{% load wagtailcore_tags wagtailimages_tags %}
{% if page.main_image %}
    {% image page. main_image width-500 %} #вывод изображения с шириной 500px
{% endif %}


Если вы добавили картинку для вашего поста, то должны получить страницу примерно такого вида.

Подробнее про работу с изображениями в wagtail можно прочитать в документации.

Теперь пора создать подраздел, в котором будут все наши посты blogindexpage.html. Добавим в blog/models.py следующий код:

class BlogIndexPage(Page):
    intro = RichTextField(blank=True)
    content_panels = Page.content_panels + [
        FieldPanel('intro', classname="full")
    ]


В папке с шаблонами создадим новый — blog/templates/blog/blog_index_page.html

и добавим в него следующий код:

{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-blogindexpage{% endblock %}
{% block content %}
    
    

{{ page.intro|richtext }}

{% endblock %}


Выполните миграцию — python manage. py makemigrations и python manage.py migrate

Теперь в админке появился шаблон страницы blogindexpage, в котором есть только текстовый блок intro. Мы добавим страницу с этим шаблоном, как дочернюю главной страницы. Ранее созданную страницу с первым постом надо будет переместить в дочерний раздел страницы blogindexpage

Пример структуры сайта: Главная страница → подраздел блоги → страница поста

Нам необходимо вывести на страницу подраздела «блоги» все посты, но если их будет много, то страница может быть очень большой. Поэтому мы будем выводить только 9 последних постов, а для просмотра остальных постов использовать пагинацию django из модуля django.core.paginator.

Внесем изменения в models.py:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class BlogIndexPage(Page):
    intro = RichTextField(blank=True)
    @property
    def blogs(self):
        # Получить список страниц блога, которые являются потомками этой страницы
        blogs = BlogPage. objects.live().descendant_of(self)
        # Сортировать по дате
        blogs = blogs.order_by('-date')
        return blogs
    def get_context(self, request):
        blogs = self.blogs
        # Пагинация
        page = request.GET.get('page')
        paginator = Paginator(blogs, 9)  # Показывать 9 постов
        try:
            blogs = paginator.page(page)
        except PageNotAnInteger:
            blogs = paginator.page(1)
        except EmptyPage:
            blogs = paginator.page(paginator.num_pages)
        # Обновить контекст шаблона
        context = super(BlogIndexPage, self).get_context(request)
        context['blogs'] = blogs
        return context
    content_panels = Page.content_panels + [
        FieldPanel('intro', classname="full")
    ]


Теперь надо создать шаблон для карточек постов. В папке blog/templates/blog создайте папку includes, в которой надо создать html шаблон blog_list_item.html — Пример пути: /blog/templates/blog/includes/blog_list_item. html

Со следующим содержанием:

{% load static wagtailcore_tags wagtailimages_tags %}
# Индивидуальная карточка поста для раздела блоги

{% if blog.main_image %}

{% image blog.main_image fill-200x200 as img %} #вывести изображение размером 200px на 200px

{% endif %}

{{ blog.date }}

{{ blog.title }}

{{ blog.intro }}


В шаблон blog/templates/blog/blog_index_page.html требуется добавить следующий код в блоке content:

        {% for blog in blogs %}
            {% include "blog/includes/blog_list_item.html" %}
        {% empty %}
            Новых постов нет
        {% endfor %}


Для реализации пагинации добавляем следующий блок на эту же страницу:

# Пагинация - используется django. core.paginator #
    


Обновляем все, теперь у вас должно работать отображение 9 последних постов в разделе блоги, также у вас появилась пагинация.

Все хорошо, осталось теперь добавить меню, для более легкого перехода между страницами нашего блога.

Меню в Wagtail работает из коробки, за него отвечает параметр «Показывать в меню:» в разделе «Продвижение», при редактировании любой страницы.


Есть подробная статья, как реализовать меню в Wagtail.

Я кратко опишу, куда и что надо добавить, чтобы у вашего сайта появилось меню, которым можно управлять из админ.панели.

Добавим в base.html:

{% load home_tags %} #home_tags.py мы создадим ниже
{% block menu %}
    {% get_site_root as site_root %}
    {% top_menu parent=site_root calling_page=self %}
{% endblock %}


Создаем в папке проекта /home/ папку /templatestag/ с файлом home_tags.py, со следующим содержанием:

from django import template
from home. models import *
from blog.models import *
register = template.Library()
@register.assignment_tag(takes_context=True)
def get_site_root(context):
    return context['request'].site.root_page
def has_menu_children(page):
    return page.get_children().live().in_menu().exists()
@register.inclusion_tag('home/tags/top_menu.html', takes_context=True)
def top_menu(context, parent, calling_page=None):
    menuitems = parent.get_children().live().in_menu()
    for menuitem in menuitems:
        menuitem.show_dropdown = has_menu_children(menuitem)
        menuitem.active = (calling_page.url.startswith(menuitem.url)
                           if calling_page else False)
    return {
        'calling_page': calling_page,
        'menuitems': menuitems,
        'request': context['request'],
    }
@register.inclusion_tag('home/tags/top_menu_children.html', takes_context=True)
def top_menu_children(context, parent):
    menuitems_children = parent.get_children()
    menuitems_children = menuitems_children. live().in_menu()
    return {
        'parent': parent,
        'menuitems_children': menuitems_children,
        'request': context['request'],
    }


Чтобы как-то стилизовать меню создаем два шаблона: top_menu.html и top_menu_children.html в папке /home/templates/home/tags/

Пишем в top_menu.html:

{% load home_tags wagtailcore_tags %}
{% get_site_root as site_root %}
  • Главная
  • {% for menuitem in menuitems %}

  • {% if menuitem.show_dropdown %}

    {% top_menu_children parent=menuitem %}
    {% else %}
    {{ menuitem.title }}
    {% endif %}

  • {% endfor %}


    Пишем в top_menu_children.html:

    {% load home_tags wagtailcore_tags %}
    

    Обратите внимание — в блоке {% load %} надо обязательно сделать вызов вашего home_tags, иначе ничего не заработает. И, конечно, не забудьте прописать все стили меню в css файл.

    Нам осталось сделать слайдер для главной страницы, чтобы она стала веселее и добавить вывод трех последних постов из раздела блоги. Для этого нам понадобиться home_tags, созданный ранее.

    За работу слайдера будет отвечать следующий код:

    В папке /home/templates/home/ создайте папку /includes/, в ней создайте файл slider.html:

    {% load wagtailimages_tags wagtailembeds_tags %}
    {% if slider_items %}
    
      {% for slider_item in slider_items %}
    • {% image slider_item.image width-1200 as imageslider %}
    • {% endfor %}
    {% endif %}


    Для wagtail можно использовать любой слайдер, например Nivo Slider, WOW или написать свой. В этом уроке я использую слайдер, который идет в комплекте с materializecss.com/media.html. Выбор слайдера для сайта дело вкуса и привычки. Чтобы слайдер работал, не забывайте добавлять все необходимые зависимости (css, js).

    Далее правим home/models.py, добавляя следующий код:

    from django.db import models
    from wagtail.wagtailcore.models import Page, Orderable
    from wagtail.wagtailcore.fields import RichTextField
    from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
                                                    InlinePanel,
                                                    MultiFieldPanel,
                                                    PageChooserPanel)
    from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
    from wagtail.wagtailsearch import index
    from modelcluster.fields import ParentalKey
    from wagtail.wagtailsnippets.models import register_snippet
    class HomePage(Page):
        body = RichTextField(blank=True)
        disc_t = RichTextField(blank=True)
        search_fields = Page.search_fields + [
            index.SearchField('body'),
            index.SearchField('disc_t'),
        ]
        content_panels = Page.content_panels + [
            InlinePanel('slider_items', label="Слайдер"), #добавляем блок управления слайдером
            FieldPanel('body', classname="full"),
            FieldPanel('disc_t', classname="full"),
        ]
    class LinkFields(models. Model):
        link_external = models.URLField("URL", blank=True)
        link_page = models.ForeignKey(
            'wagtailcore.Page',
            null=True,
            blank=True,
            related_name='+'
        )
        @property
        def link(self):
            if self.link_page:
                return self.link_page.url
            else:
                return self.link_external
        panels = [
            FieldPanel('link_external'),
            PageChooserPanel('link_page'),
        ]
        class Meta:
            abstract = True
    class SliderItem(LinkFields):
        image = models.ForeignKey(
            'wagtailimages.Image',
            null=True,
            blank=True,
            on_delete=models.SET_NULL,
            related_name='+'
        )
        panels = [
            ImageChooserPanel('image')
        ]
        class Meta:
            abstract = True
    class HomePageSliderItem(Orderable, SliderItem):
        page = ParentalKey('HomePage', related_name='slider_items')
    


    Обновляемся, делаем миграции, перезапускаем сервер и открыв редактирование главной страницы увидим новый блок со слайдером.

    Для отображения трех последних постов на главной странице, добавим следующий код:

    В /home/templatestag/home_tags.py добавить:

    @register.inclusion_tag(
        'home/tags/blog_listing_homepage.html',
        takes_context=True
    )
    def blog_listing_homepage(context, count=3): #count=3 выводит 3 последних поста
        blogs = BlogPage.objects.live().order_by('-date') #фильтр по дате от последнего поста
        return {
            'blogs': blogs[:count].select_related('main_image'),
            'request': context['request'],
        }
    


    В папку /home/templates/home/tags/ добавить шаблон blog_listing_homepage.html, с содержанием:

    {% if blogs %}
          {% for blog in blogs %}
            {% include "blog/includes/blog_list_item.html" %}
          {% endfor %}
    {% endif %}
    


    Чтобы вывести посты на главную страницу добавим в home_page.html после слайдера:

    {% blog_listing_homepage %}

    Обязательно сделайте нормальную разметку по блокам для домашней страницы, чтобы весь контент не висел одной кучей. Делаем миграции, обновляемся, и видим на главной странице слайдер и три последних поста (если вы их создали, конечно)

    У нас почти готов простой блог, есть главная страница, раздел блоги, и можно посмотреть каждый пост отдельно. Мы можем создавать новые разделы, управлять постами, менять изображения. Для начала этого хватает.

    Добавим хлебные крошки, для лучшей навигации по блогу и наш проект готов для старта.

    Реализуется это следующим кодом в шаблонах blog_page.html и blog_index_page.html:

             {% if self.get_ancestors|length > 1 %}
                

    {% for page in self.get_ancestors %} {% if page.is_root == False %} {{ page.title }} {% endif %} {% endfor %} {{ self.title }}

    {% endif %}


    Оформляем блок стилями и получаем удобную навигацию в дополнение к меню сайта.

    Весь остальной функционал можно добавить по аналогии, создать другие разделы, использовать для разных страниц разные шаблоны, прикрепить баннеры и прочее.

    Надеюсь, что этот базовый урок помог кому-то начать знакомство с Wagtail CMS. В следующей части напишу про использование StreamField.

    python — Django CMS — невозможно изменить структуру недавно добавленной веб-страницы

    Я совершенно не знаком с Django CMS, и я застрял с этой проблемой.

    Я добавил новый модуль в существующий проект Django и создал новую HTML-страницу. Это конфигурация шаблонов в settings.py

     ШАБЛОНЫ = [
        {
            'БЭКЭНД': 'django.template.backends.django.DjangoTemplates',
            «КАТАЛОГИ»: [os.path.join (BASE_DIR, «site_cms», «шаблоны»),
                     ],
            'ПАРАМЕТРЫ': {
                'контекстные_процессоры': [
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    'django.template.context_processors.i18n',
                    'django.template.context_processors.debug',
                    'django.template. context_processors.request',
                    'django.template.context_processors.media',
                    'django.template.context_processors.csrf',
                    'django.template.context_processors.tz',
                    'sekizai.context_processors.sekizai',
                    'django.template.context_processors.static',
                    'cms.context_processors.cms_settings',
                    'core.context_processors.request_info',
                ],
                'грузчики': [
                    'django.template.loaders.filesystem.Loader',
                    'django.template.loaders.app_directories.Loader',
                    'django.template.loaders.eggs.Loader'
                ],
            },
        },
    ]
     

    На новой странице я расширяю домашнюю страницу веб-сайта, как это делают другие страницы. Это домашняя страница home.html (/core/templates/core/home.html):

     {% load i18n easy_thumbnails_tags static %}
    
    
    <голова>
        {% загрузить статические файлы i18n menu_tags%}
    
    <основной>
        <дел>
            {% заблокировать содержимое %}
     

    Это моя новая страница newpage. html (/newpage/templates/newpage/newpage.html)

     {% расширяет "home.html" %}
    {% load easy_thumbnails_tags i18n static core_filters bootstrap4 %}
    {% заблокировать содержимое %}
        {% загрузить бутстрап4%}
        <дел>
     

    После создания новой страницы я добавил ее в главное меню сайта через панель Django CMS. Я выбрал шаблон для страницы тот, который использует родитель (домашний). Я вижу, что это вносит изменения только в базу данных. Итак, теперь у меня есть эта страница в меню главной страницы и в модуле Django CMS.

    У меня проблема в том, что я не могу редактировать структуру страницы из панели Django CMS. Когда я нажимаю кнопку «Изменить», я вижу значок структуры (www.localhost:8000/newpage/?structure), но кнопка не активна. Я хочу иметь возможность добавлять виджеты на эту страницу. Как я могу это сделать? Как я могу активировать возможность изменения структуры?

    В этом проекте я вижу, что на некоторых страницах есть возможность изменять структуру страницы, а на других нет. Может быть актуально, когда я проверяю источник других страниц с этой возможностью, я вижу:

     'request': {
            'язык': 'ан',
            'модель': 'cms.page',
            'id_страницы': '3',
            «пк»: «3»,
            'url': '/admin/cms/page/resolve/',
            'панель инструментов': '/admin/cms/usersettings/cms-toolbar/'
        },
     

    на моей новой странице я вижу:

     'запрос': {
            'язык': 'ан',
            'модель': '',
            'id_страницы': '103',
            'пк': '',
            'url': '/admin/cms/page/resolve/',
            'панель инструментов': '/admin/cms/usersettings/cms-toolbar/'
        },
     

    Я использую Python 3.6.9, Django 1.11.17 и django-cms 3.5.3.
    Я знаю, что мне может не хватать некоторой соответствующей информации/кода для отображения. Пожалуйста, спрашивайте, я опубликую.

    python — Как отобразить данные модели django на шаблоне страницы django cms

    Задай вопрос

    спросил

    Изменено
    3 года, 8 месяцев назад

    Просмотрено
    1к раз

    Я хотел бы иметь возможность использовать данные внешнего приложения на странице django cms.
    Я могу использовать пользовательские данные плагина, но не данные из обычного приложения django

    Я пытался создать представления для обработки своих данных, но как мне вызвать это представление со страниц django cms?
    вот именно то, о чем я прошу, но его объяснение поверхностно, а ссылка, указанная в ответе, больше не используется.

    Вот моя модель:

     класс ExternalArticle(models.Model):
        URL-адрес = модели.URLField()
        источник = модели.CharField(
            максимальная_длина=100,
            help_text="Пожалуйста, укажите источник статьи",
            verbose_name="источник статьи",
        )
        название = модели.CharField(
            максимальная_длина=250,
            help_text="Пожалуйста, укажите название статьи",
            verbose_name="название статьи",
        )
        Мета класса:
            заказ = ["-original_publication_date"]
        защита __str__(я):
            вернуть u"%s:%s" % (self.source[0:60], self.title[0:60])
     

    В моем шаблоне есть заполнители

     {% load cms_tags %}
    {% заголовок блока %}{% page_attribute "page_title" %}{% заголовок блока %}
    {% заблокировать содержимое %}
        <раздел>
            <дел>
                 <дел>
                        
                        <дел>
                            <дел>
                               {% заполнитель "заголовок" %}