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:
有一种扩展页面和标题模型的官方方法,我强烈推荐这个官方文档:
- Extending the page & title models from docs.django-cms.org
- 从docs.django-cms.org扩展页面和标题模型
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:
-
Create a subclass of
PageExtension
in yourmodels.py
file and register it:在模型中创建PageExtension的子类。py文件并进行注册:
class IconExtension(PageExtension): image = models.ImageField(upload_to='icons') extension_pool.register(IconExtension)
-
Create also a subclass of
PageExtensionAdmin
in youradmin.py
file and register it:在您的admin中创建PageExtensionAdmin的子类。py文件并进行注册:
class IconExtensionAdmin(PageExtensionAdmin): pass admin.site.register(IconExtension, IconExtensionAdmin)
-
Finally, to make it accessible from the toolbar, create a subclass of
ExtensionToolbar
incms_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:
有一种扩展页面和标题模型的官方方法,我强烈推荐这个官方文档:
- Extending the page & title models from docs.django-cms.org
- 从docs.django-cms.org扩展页面和标题模型
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:
-
Create a subclass of
PageExtension
in yourmodels.py
file and register it:在模型中创建PageExtension的子类。py文件并进行注册:
class IconExtension(PageExtension): image = models.ImageField(upload_to='icons') extension_pool.register(IconExtension)
-
Create also a subclass of
PageExtensionAdmin
in youradmin.py
file and register it:在您的admin中创建PageExtensionAdmin的子类。py文件并进行注册:
class IconExtensionAdmin(PageExtensionAdmin): pass admin.site.register(IconExtension, IconExtensionAdmin)
-
Finally, to make it accessible from the toolbar, create a subclass of
ExtensionToolbar
incms_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项目)。