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

pmo*_*niq 15 django django-admin django-cms

我想在django-cms中添加一些额外的字段(在django管理面板中).这怎么用最简单的方式?

Tim*_*ony 25

创建一个新应用程序(称为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(...)
Run Code Online (Sandbox Code Playgroud)

然后创建一个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)
Run Code Online (Sandbox Code Playgroud)

这会将您的扩展模型添加为您创建的任何页面的内联.访问扩展模型设置的最简单方法是创建上下文处理器:

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,
    }
Run Code Online (Sandbox Code Playgroud)

现在,您可以{{ extended_page_options.my_extra_field }}在模板中使用当前页面的额外选项

基本上你正在做的是创建一个单独的模型,其中包含额外的设置,用作每个CMS页面的内联.我以前从博客文章中得到了这个,如果我能发现我会发布它.

编辑

这是博客文章:http://ilian.ini.org/extending-django-cms-page-model/

  • 请注意,正如我在博客文章中评论的那样,如果您通过Page对象本身访问数据,则不需要上下文处理器.也许Timmy的方式更清楚,因为你不需要在模板中写出整个"request.current_page.extended_fields.all ..."的东西,但对我来说这是一个额外的重载,如果我不想,我想跳过所有页面都需要它.一般来说,这是编码风格的问题. (4认同)
  • 他们现在在> 2.4 [sof ref](http://stackoverflow.com/a/16852790/707580)中使用`request.current_page.publisher_draft.extended_fields.page_image`.我认为这对像我这样谷歌的人很有帮助. (4认同)

Ben*_*vis 6

还有一种方法可以在不使用内联的情况下执行此操作,并在页面表单的任何位置使用字段.例如,我有一个"颜色方案"的自定义设置,我希望在"基本设置"字段集下.这可以通过覆盖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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)


Fli*_*imm 6

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

如果可以,我还强烈建议使用占位符,因为写这个答案,我现在更喜欢为封面图像的用例创建一个占位符.(如果需要,您甚至可以在模板中获取图像URL).

链接摘要:

  1. PageExtensionmodels.py文件中创建一个子类并注册它:

    class IconExtension(PageExtension):
        image = models.ImageField(upload_to='icons')
    
    extension_pool.register(IconExtension)
    
    Run Code Online (Sandbox Code Playgroud)
  2. PageExtensionAdminadmin.py文件中创建一个子类并注册它:

    class IconExtensionAdmin(PageExtensionAdmin):
        pass
    
    admin.site.register(IconExtension, IconExtensionAdmin)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 最后,要使其可以从工具栏访问,请创建ExtensionToolbarin 的子类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)
    
    Run Code Online (Sandbox Code Playgroud)

官方文档更详细和解释.

添加对常规和高级"页面设置"对话框中添加元素的支持时,存在一个开放的GitHub问题.


sth*_*hzg 5

我是通过 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> }}
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

要在模板中访问其值:

{{ request.current_page.showdefaultheaderextension.show_header }}
Run Code Online (Sandbox Code Playgroud)