我想在Django FlatPage数据库模型中添加一个字段,但我真的不知道如何在不编辑原始应用程序的情况下扩展它。
我想要做的是将以下字段添加到模型中:
from django.db import models
from django.contrib.flatpages.models import FlatPage as FlatPageOld
class FlatPage(FlatPageOld):
order = models.PositiveIntegerField(unique=True)
如何将其添加到FlatPage模型中?
提前致谢
答案 0 :(得分:21)
您的方法很好 - 您只是看不到结果,因为旧的平面模型已在管理员中注册而新的平面模型未注册。以下是您在新应用程序的admin.py中可能会执行的操作(使用的命名方式比上面提到的更少):
from django.contrib import admin
from django.contrib.flatpages.admin import FlatPageAdmin
from django.contrib.flatpages.forms import FlatpageForm
from django.contrib.flatpages.models import FlatPage
from models import ExtendedFlatPage
class ExtendedFlatPageForm(FlatpageForm):
class Meta:
model = ExtendedFlatPage
class ExtendedFlatPageAdmin(FlatPageAdmin):
form = ExtendedFlatPageForm
fieldsets = (
(None, {'fields': ('url', 'title', 'content', 'sites', 'order')}),
)
admin.site.unregister(FlatPage)
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin)
显然这里有一些事情,但最重要的是FlatPage模型正在取消注册,而ExtendedFlatPage模型正在其位置注册。
答案 1 :(得分:7)
你帖子中的方法不起作用,因为......?
如果由于某种原因你真的需要摆弄内置的FlatPage类并动态编辑它,你可以挂钩到class_prepared信号:
http://docs.djangoproject.com/en/dev/ref/signals/#class-prepared
修改强>
以下是使用class_prepared执行此操作的方法:
from django.db.models.signals import class_prepared
from django.db import models
def alter_flatpages(sender, **kwargs):
if sender.__module__ == 'django.contrib.flatpages.models' and sender.__name__ == 'FlatPage':
order = models.IntegerField()
order.contribute_to_class(sender, 'order')
class_prepared.connect(alter_flatpages)
将此信息放入与settings.py位于同一目录中的'signals.py'中,并将“信号”添加到顶部(这一点非常重要,以确保信号处理程序安装时间安装在INSTALLED_APPS列表中。
但是,仍然无法在Admin中显示该字段,因为FlatPages有一个自定义的ModelAdmin类,它明确地列出了字段。因此,在flatpages应用程序中注册后,您需要在某处取消注册(admin.site.unregister)并注册您自己的ModelAdmin。
答案 2 :(得分:0)
settings.py
应用程序的django.contrib.flatpages
change the location of the migrations folder中将应用程序移到默认文件夹以外的其他文件夹。例如: settings.py
:
MIGRATION_MODULES = {'flatpages': 'yourproject.flatpages.migrations'}
请记住,您必须在文件夹__init__.py
,yourproject
和flatpages
中创建空的migrations
文件,以使Python
对待那些文件字典作为包。
执行makemigrations
管理命令以将初始迁移填充到MIGRATION_MODULES
文件夹中。它的外观应类似于default one。
在您的一个应用程序(最好是使用平板功能的应用程序)的apps.py
中,添加oggy的class_prepared
解决方案:
apps.py
:
from django.apps import AppConfig
from django.db.models.signals import class_prepared
from django.db import models
def alter_flatpages(sender, **kwargs):
if sender.__module__ == 'django.contrib.flatpages.models' and sender.__name__ == 'FlatPage':
meta_description = models.CharField(max_length=255, blank=True, null=True)
meta_description.contribute_to_class(sender, 'meta_description')
class TexteConfig(AppConfig):
name = 'marlene.texte'
def __init__(self, app_name, app_module):
super().__init__(app_name, app_module)
class_prepared.connect(alter_flatpages)
通过再次执行makemigrations
添加另一个迁移。这次您已将CharField
meta_description
添加到模型中。 migrate
将更改应用到数据库。
修改FlatPageAdmin
:
admin.py
:
from django.contrib.flatpages.admin import FlatPageAdmin
from django.contrib.flatpages.models import FlatPage
class MarleneFlatPageAdmin(FlatPageAdmin):
fieldsets = (
(None, {'fields': ('url', 'title', 'content', 'meta_description', 'sites')}),
(_('Advanced options'), {
'classes': ('collapse',),
'fields': ('registration_required', 'template_name'),
}),
)
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, MarleneFlatPageAdmin)
该解决方案的最大缺点是,如果Django
将来将新的迁移添加到平板应用程序,则您要负责管理它们。我建议大家,无论是否适合您当前的情况,都不要使用平板应用程序。