如何在django-cms中添加一些额外的字段?(在django管理面板)

时间:2021-11-18 07:23:47

I would like to add some extra fields to pages in django-cms (in django admin panel). How do this in the simplest way?

我想在django-cms (django管理面板)中向页面添加一些额外的字段。用最简单的方法怎么做?

5 个解决方案

#1


25  

Create a new app (called extended_cms or something) and in models.py create the following:

创建一个新的应用程序(称为extended_cms或其他)并在模型中创建。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(...)

then create an admin.py:

然后创建一个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)

which will add your extended model to as an inline to any page you create. The easiest way to access the extended model setttings, is to create a context processor:

它将您的扩展模型作为内联添加到您创建的任何页面。访问扩展模型设置的最简单方法是创建一个上下文处理器:

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,
    }

and now you have access to your extra options for the current page using {{ extended_page_options.my_extra_field }} in your templates

现在您可以使用{{{{extended_page_options)访问当前页面的额外选项。在模板中使用my_extra_field}。

Essentially what you are doing is creating a separate model with extra settings that is used as an inline for every CMS Page. I got this from a blog post previously so if I can find that I'll post it.

实际上,您所做的是创建一个单独的模型,并使用额外的设置作为每个CMS页面的内联。这是我之前在博客上看到的,所以如果我能找到的话,我会把它贴出来。

EDIT

编辑

Here is the blog post: http://ilian.i-n-i.org/extending-django-cms-page-model/

这里有一个博客帖子:http://ilian.i-n- i.org/extendingdjango -cms-page-model/。

#2


6  

There's also a way to do this without using an inline, and having the fields anywhere on the Page form. For example, I have a custom setting for "color scheme" that I wanted to be under the "Basic Settings" fieldset. This can be done by overriding the ModelForm and the ModelAdmin's fieldsets. Also, I opted for a OneToOne field instead of a ForeignKey, for simplicity's sake.

还有一种方法可以不使用内联,在页面窗体的任何地方都有字段。例如,我有一个“颜色方案”的自定义设置,我想把它放在“基本设置”字段集中。这可以通过覆盖ModelForm和ModelAdmin的字段集来实现。而且,为了简单起见,我选择了一个单一的字段,而不是一个外键。

models.py:

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:

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)

#3


5  

There is an official way to extend the page & title models, I highly recommend this official documentation:

有一种扩展页面和标题模型的官方方法,我强烈推荐这个官方文档:

I also highly recommend using a placeholder if you can, since writing this answer, I now prefer creating a placeholder for the use case of cover images. (You can even get just the image URL in your template if you want to).

如果可以的话,我也强烈建议使用占位符,因为编写这个答案,我现在更喜欢为cover映像的用例创建占位符。(如果您愿意,甚至可以在模板中获得图像URL)。

Summary of the link:

  1. Create a subclass of PageExtension in your models.py file and register it:

    在模型中创建PageExtension的子类。py文件并进行注册:

    class IconExtension(PageExtension):
        image = models.ImageField(upload_to='icons')
    
    extension_pool.register(IconExtension)
    
  2. Create also a subclass of PageExtensionAdmin in your admin.py file and register it:

    在您的admin中创建PageExtensionAdmin的子类。py文件并进行注册:

    class IconExtensionAdmin(PageExtensionAdmin):
        pass
    
    admin.site.register(IconExtension, IconExtensionAdmin)
    
  3. Finally, to make it accessible from the toolbar, create a subclass of ExtensionToolbar in cms_toolbars.py and register it:

    最后,要从工具栏中访问它,请在cms_toolbars中创建一个ExtensionToolbar子类。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)
    

The official documentation goes into more detail and explanation.

官方文件更详细和解释。

There is an open GitHub issue on adding support for adding elements to the normal and advanced "page settings" dialogues.

有一个开放的GitHub问题,关于添加元素到正常和高级的“页面设置”对话中的支持。

#4


4  

I've got here via Google and the answers got me on the right track for Django CMS 3 Beta. To extend the page model and hook your extension into the toolbar, you can follow along the official documentation:

我是通过谷歌来的,答案让我找到了Django CMS 3测试版的正确轨道。要扩展页面模型并将扩展连接到工具栏中,您可以遵循官方文档:

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

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

Access value in template

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

For example, I extended the page model with this model:

例如,我用这个模型扩展了页面模型:

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)

To access its values in the template:

在模板中访问其值:

{{ request.current_page.showdefaultheaderextension.show_header }}

#5


3  

Since I dont have enough reputation I cannot comment on Timmy O'Mahony's Post directly. However I want to note that the proposed solution of adding a StackedInline Object to the PageAdmin.inlines list does not work any more as supposed.

由于我没有足够的声誉,我不能直接评论蒂米·奥马奥尼的帖子。但是,我想指出的是,向PageAdmin添加一个StackedInline对象的建议解决方案。inlines列表不再按预期工作。

I'm working with Djangocms 3.3 and somewhere between Timmy O'Mahony's version any mine the authors changed the semantic of the inline List. It's content is now shown in the Permissions Menu for that specific page (including possibly added futher StackedInline or TabularInline items).

我正在使用Djangocms 3.3,在Timmy O'Mahony的任何版本之间,作者改变了内联列表的语义。它的内容现在显示在特定页面的权限菜单中(包括可能添加的futher StackedInline或TabularInline项目)。

#1


25  

Create a new app (called extended_cms or something) and in models.py create the following:

创建一个新的应用程序(称为extended_cms或其他)并在模型中创建。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(...)

then create an admin.py:

然后创建一个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)

which will add your extended model to as an inline to any page you create. The easiest way to access the extended model setttings, is to create a context processor:

它将您的扩展模型作为内联添加到您创建的任何页面。访问扩展模型设置的最简单方法是创建一个上下文处理器:

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,
    }

and now you have access to your extra options for the current page using {{ extended_page_options.my_extra_field }} in your templates

现在您可以使用{{{{extended_page_options)访问当前页面的额外选项。在模板中使用my_extra_field}。

Essentially what you are doing is creating a separate model with extra settings that is used as an inline for every CMS Page. I got this from a blog post previously so if I can find that I'll post it.

实际上,您所做的是创建一个单独的模型,并使用额外的设置作为每个CMS页面的内联。这是我之前在博客上看到的,所以如果我能找到的话,我会把它贴出来。

EDIT

编辑

Here is the blog post: http://ilian.i-n-i.org/extending-django-cms-page-model/

这里有一个博客帖子:http://ilian.i-n- i.org/extendingdjango -cms-page-model/。

#2


6  

There's also a way to do this without using an inline, and having the fields anywhere on the Page form. For example, I have a custom setting for "color scheme" that I wanted to be under the "Basic Settings" fieldset. This can be done by overriding the ModelForm and the ModelAdmin's fieldsets. Also, I opted for a OneToOne field instead of a ForeignKey, for simplicity's sake.

还有一种方法可以不使用内联,在页面窗体的任何地方都有字段。例如,我有一个“颜色方案”的自定义设置,我想把它放在“基本设置”字段集中。这可以通过覆盖ModelForm和ModelAdmin的字段集来实现。而且,为了简单起见,我选择了一个单一的字段,而不是一个外键。

models.py:

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:

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)

#3


5  

There is an official way to extend the page & title models, I highly recommend this official documentation:

有一种扩展页面和标题模型的官方方法,我强烈推荐这个官方文档:

I also highly recommend using a placeholder if you can, since writing this answer, I now prefer creating a placeholder for the use case of cover images. (You can even get just the image URL in your template if you want to).

如果可以的话,我也强烈建议使用占位符,因为编写这个答案,我现在更喜欢为cover映像的用例创建占位符。(如果您愿意,甚至可以在模板中获得图像URL)。

Summary of the link:

  1. Create a subclass of PageExtension in your models.py file and register it:

    在模型中创建PageExtension的子类。py文件并进行注册:

    class IconExtension(PageExtension):
        image = models.ImageField(upload_to='icons')
    
    extension_pool.register(IconExtension)
    
  2. Create also a subclass of PageExtensionAdmin in your admin.py file and register it:

    在您的admin中创建PageExtensionAdmin的子类。py文件并进行注册:

    class IconExtensionAdmin(PageExtensionAdmin):
        pass
    
    admin.site.register(IconExtension, IconExtensionAdmin)
    
  3. Finally, to make it accessible from the toolbar, create a subclass of ExtensionToolbar in cms_toolbars.py and register it:

    最后,要从工具栏中访问它,请在cms_toolbars中创建一个ExtensionToolbar子类。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)
    

The official documentation goes into more detail and explanation.

官方文件更详细和解释。

There is an open GitHub issue on adding support for adding elements to the normal and advanced "page settings" dialogues.

有一个开放的GitHub问题,关于添加元素到正常和高级的“页面设置”对话中的支持。

#4


4  

I've got here via Google and the answers got me on the right track for Django CMS 3 Beta. To extend the page model and hook your extension into the toolbar, you can follow along the official documentation:

我是通过谷歌来的,答案让我找到了Django CMS 3测试版的正确轨道。要扩展页面模型并将扩展连接到工具栏中,您可以遵循官方文档:

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

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

Access value in template

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

For example, I extended the page model with this model:

例如,我用这个模型扩展了页面模型:

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)

To access its values in the template:

在模板中访问其值:

{{ request.current_page.showdefaultheaderextension.show_header }}

#5


3  

Since I dont have enough reputation I cannot comment on Timmy O'Mahony's Post directly. However I want to note that the proposed solution of adding a StackedInline Object to the PageAdmin.inlines list does not work any more as supposed.

由于我没有足够的声誉,我不能直接评论蒂米·奥马奥尼的帖子。但是,我想指出的是,向PageAdmin添加一个StackedInline对象的建议解决方案。inlines列表不再按预期工作。

I'm working with Djangocms 3.3 and somewhere between Timmy O'Mahony's version any mine the authors changed the semantic of the inline List. It's content is now shown in the Permissions Menu for that specific page (including possibly added futher StackedInline or TabularInline items).

我正在使用Djangocms 3.3,在Timmy O'Mahony的任何版本之间,作者改变了内联列表的语义。它的内容现在显示在特定页面的权限菜单中(包括可能添加的futher StackedInline或TabularInline项目)。