18

我想在 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 模型?

提前致谢

4

3 回答 3

25

您的方法很好-您只是看不到结果,因为旧的平面模型已在管理员中注册,而新的则没有。以下是您可能在新应用程序的 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 模型正在其位置注册。

于 2009-06-21T13:32:33.827 回答
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。

于 2009-06-20T13:02:07.927 回答
0
  1. 在您将应用程序settings.py 的迁移文件夹的位置更改为django.contrib.flatpages默认文件夹之外的另一个文件夹。例如:

settings.py

MIGRATION_MODULES = {'flatpages': 'yourproject.flatpages.migrations'}

请记住,您必须在文件夹中创建空文件__init__.pyyourproject并将flatpages这些字典视为包。migrationsPython

  1. 执行makemigrations管理命令将初始迁移填充到您的MIGRATION_MODULES文件夹。它应该与默认的相似。

  2. apps.py您的一个应用程序中(最好是使用 flatpages 功能的应用程序)添加 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)
  1. makemigrations通过再次执行添加另一个迁移。这次您已将 添加CharField meta_description到模型中。migrate将更改应用到数据库。

  2. 修改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将来向平面应用程序添加新的迁移,您将负责管理它们。我建议大家不要使用平面应用程序,无论它是否适合您当前的情况。

于 2020-05-11T06:04:42.127 回答