Как добавить дополнительные поля на страницу в django-cms? (в панели администратора джанго)

Я хотел бы добавить несколько дополнительных полей на страницы в django-cms (в панели администратора django). Как это сделать самым простым способом?


person pmoniq    schedule 24.04.2012    source источник
comment
вы хотите показать эти поля в админке и эти поля уже существуют в модели? Или вы хотите добавить новые поля к существующим моделям?   -  person kender    schedule 24.04.2012
comment
@kender - новый.. Мне все еще нужна помощь :)   -  person pmoniq    schedule 24.04.2012
comment
вы можете добавить эти поля в модель CMS, не так ли? затем создайте схему миграции (думаю, Django-cms использует для этого South). Тогда все, что осталось, это изменить/обезьянить патчи классов ModelAdmin для измененных моделей...   -  person kender    schedule 24.04.2012


Ответы (5)


Создайте новое приложение (с именем extended_cms или как-то так) и в models.py создайте следующее:

from django.db import models
from django.utils.translation import ugettext_lazy as _
from cms.models.pagemodel import Page

class ExtendedPage(models.Model):   
    page = models.ForeignKey(Page, unique=True, verbose_name=_("Page"), editable=False, related_name='extended_fields')
    my_extra_field = models.CharField(...)

затем создайте admin.py:

from models import ExtendedPage
from cms.admin.pageadmin import PageAdmin
from cms.models.pagemodel import Page
from django.contrib import admin

class ExtendedPageAdmin(admin.StackedInline):
    model = ExtendedPage
    can_delete = False

PageAdmin.inlines.append(ExtendedPageAdmin)
try:
    admin.site.unregister(Page)
except:
    pass
admin.site.register(Page, PageAdmin)

который добавит вашу расширенную модель в качестве встроенной на любую страницу, которую вы создаете. Самый простой способ получить доступ к расширенным настройкам модели — создать контекстный процессор:

from django.core.cache import cache
from django.contrib.sites.models import Site

from models import ExtendedPage

def extended_page_options(request):
    cls = ExtendedPage
    extended_page_options = None    
    try:
        extended_page_options = request.current_page.extended_fields.all()[0]
    except:
        pass
    return {
        'extended_page_options' : extended_page_options,
    }

и теперь у вас есть доступ к вашим дополнительным параметрам для текущей страницы, используя {{ extended_page_options.my_extra_field }} в ваших шаблонах

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

ИЗМЕНИТЬ

Вот сообщение в блоге: http://ilian.ini.org/extending-django-cms-page-model/

person Timmy O'Mahony    schedule 24.04.2012
comment
Обратите внимание, что, как я прокомментировал в своем блоге, процессор контекста не требуется, если вы получаете доступ к данным через сами объекты страницы. Возможно, способ Тимми более понятен, потому что вам не нужно будет писать весь request.current_page.extended_fields.all... в шаблоне, но для меня это дополнительная перегрузка, которую я хотел бы пропустить, если она мне не нужна. это для всех страниц. Как правило, это вопрос стиля кодирования. - person Ilian Iliev; 15.01.2013
comment
Теперь они используют request.current_page.publisher_draft.extended_fields.page_image в › 2.4 sof ref. Я думаю, что это полезно для таких людей из Google, как я. - person hbrls; 12.11.2013
comment
@hbrlovehaku спасает жизнь! - person Hedde van der Heide; 16.04.2014
comment
По какой-то причине я не могу сделать так, чтобы ExtendedPageAdmin отображалось в интерфейсе администратора. - person Flimm; 11.08.2016

Также есть способ сделать это без использования встроенных полей и наличия полей в любом месте формы страницы. Например, у меня есть пользовательская настройка для «цветовой схемы», которую я хотел разместить в наборе полей «Основные настройки». Это можно сделать, переопределив наборы полей ModelForm и ModelAdmin. Кроме того, для простоты я выбрал поле OneToOne вместо ForeignKey.

models.py:

from django.db import models
from cms.models.pagemodel import Page
from django.conf import settings

class PageCustomSettings(models.Model):
    page = models.OneToOneField(Page, editable=False, 
                                related_name='custom_settings')
    color_scheme = models.CharField(blank=True, choices=settings.COLOR_SCHEMES,
                                    max_length=20)

admin.py:

from django import forms
from django.conf import settings
from django.contrib import admin
from cms.admin.pageadmin import PageAdmin, PageForm
from cms.models.pagemodel import Page
from web.models import PageCustomSettings

color_scheme_choices = (('', '---------'),) + settings.COLOR_SCHEMES

class CustomPageForm(PageForm):
    color_scheme = forms.ChoiceField(choices=color_scheme_choices,
                                     required=False)

    def __init__(self, *args, **kwargs):
        # make sure that when we're changing a current instance, to set the 
        # initial values for our custom fields
        obj = kwargs.get('instance')
        if obj:
            try:
                opts = obj.custom_settings
                kwargs['initial'] = {
                    'color_scheme': opts.color_scheme
                }
            except PageCustomSettings.DoesNotExist:
                pass
        super(CustomPageForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        # set the custom field values when saving the form
        obj = super(CustomPageForm, self).save(commit)
        try:
            opts = PageCustomSettings.objects.get(page=obj)
        except PageCustomSettings.DoesNotExist:
            opts = PageCustomSettings(page=obj)
        opts.color_scheme = self.cleaned_data['color_scheme']
        opts.save()
        return obj

PageAdmin.form = CustomPageForm
PageAdmin.fieldsets[1][1]['fields'] += ['color_scheme']

admin.site.unregister(Page)
admin.site.register(Page, PageAdmin)
person Ben Davis    schedule 12.03.2013
comment
очень красивое решение. Спасибо! - person Simanas; 18.07.2013
comment
Очень хорошее решение, хотя, когда я публикую свою страницу в CMS, создается новая страница, не копирующая новые свойства на опубликованную страницу. - person Daniel Tate; 23.04.2014
comment
PageAdmin.fieldsets для меня нет. - person Flimm; 11.08.2016

Существует официальный способ расширения моделей страниц и заголовков, я настоятельно рекомендую эту официальную документацию:

Я также настоятельно рекомендую использовать заполнитель, если вы можете, поскольку после написания этого ответа я теперь предпочитаю создавать заполнитель для варианта использования обложек. (Вы даже можете получить только URL-адрес изображения в своем шаблоне, если хотите).

Резюме ссылки:

  1. Создайте подкласс PageExtension в файле models.py и зарегистрируйте его:

    class IconExtension(PageExtension):
        image = models.ImageField(upload_to='icons')
    
    extension_pool.register(IconExtension)
    
  2. Создайте также подкласс PageExtensionAdmin в файле admin.py и зарегистрируйте его:

    class IconExtensionAdmin(PageExtensionAdmin):
        pass
    
    admin.site.register(IconExtension, IconExtensionAdmin)
    
  3. Наконец, чтобы сделать его доступным с панели инструментов, создайте подкласс ExtensionToolbar в cms_toolbars.py и зарегистрируйте его:

    @toolbar_pool.register
    class IconExtensionToolbar(ExtensionToolbar):
        model = IconExtension
    
        def populate(self):
            current_page_menu = self._setup_extension_toolbar()
            if current_page_menu:
                page_extension, url = self.get_page_extension_admin()
                if url:
                    current_page_menu.add_modal_item(_('Page Icon'), url=url,
                        disabled=not self.toolbar.edit_mode)
    

Официальная документация содержит более подробную информацию и пояснения.

Существует открытый вопрос GitHub по добавлению поддержки добавления элементов в обычные и расширенные "настройки страницы". " диалоги.

person Flimm    schedule 11.08.2016
comment
Определенно новее, проще, проще и лучше - я как-то пропустил это дополнение. Спасибо! - person The NetYeti; 27.04.2017

Я попал сюда через Google, и ответы помогли мне выбрать правильный путь для Django CMS 3 Beta. Чтобы расширить модель страницы и подключить ваше расширение к панели инструментов, вы можете следовать официальной документации:

http://django-cms.readthedocs.org/en/latest/how_to/extending_page_title.html

Значение доступа в шаблоне

{{ request.current_page.<your_model_class_name_in_lowercase>.<field_name> }}

Например, я расширил модель страницы с помощью этой модели:

from django.db import models

from cms.extensions import PageExtension
from cms.extensions.extension_pool import extension_pool


class ShowDefaultHeaderExtension(PageExtension):
    show_header = models.BooleanField(default=True)

extension_pool.register(ShowDefaultHeaderExtension)

Чтобы получить доступ к его значениям в шаблоне:

{{ request.current_page.showdefaultheaderextension.show_header }}
person sthzg    schedule 18.02.2014

Поскольку у меня недостаточно репутации, я не могу напрямую комментировать сообщение Тимми О'Махони. Однако я хочу отметить, что предлагаемое решение добавления объекта StackedInline в список PageAdmin.inlines больше не работает, как предполагалось.

Я работаю с Djangocms 3.3, и где-то между версией Тимми О'Махони и моей авторы изменили семантику встроенного списка. Его содержимое теперь отображается в меню разрешений для этой конкретной страницы (включая, возможно, добавленные дополнительные элементы StackedInline или TabularInline).

person K Moe    schedule 16.08.2016