在不更改原始Django App的情况下向Django FlatPages添加功能

14 django monkeypatching django-models

我想在Django FlatPage数据库模型中添加一个字段,但我真的不知道如何在不编辑原始应用程序的情况下扩展它.

我想要做的是将以下字段添加到模型:


from django.db import models
from django.contrib.flatpages.models import FlatPage as FlatPageOld

class FlatPage(FlatPageOld):
    order = models.PositiveIntegerField(unique=True)
Run Code Online (Sandbox Code Playgroud)

如何将其添加到FlatPage模型?

提前致谢

oza*_*zan 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)
Run Code Online (Sandbox Code Playgroud)

显然这里有一些事情,但最重要的是FlatPage模型正在取消注册,而ExtendedFlatPage模型正在其位置注册.

  • 请记住,此方法不适用于默认的FlatpageFallbackMiddleware - 它将返回原始Flatpage模型的实例,而不是您的扩展.因此,您必须编写自己的版本,或使用自己的URL /视图.此外,您现在有两个表,其中只需要一个表,这会导致查询效率降低.总而言之,我建议从头开始编写自己的平面应用程序,或者使用class_prepared方法对字段进行monkeypatch,而不是使用继承. (8认同)

ogg*_*ggy 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)
Run Code Online (Sandbox Code Playgroud)

把它放在与settings.py相同的目录中的'signals.py'中,并在INSTALLED_APPS列表中添加'信号'到顶部(这对于确保及时安装信号处理程序很重要).

但是,这仍然不会在Admin中显示该字段,因为FlatPages有一个自定义的ModelAdmin类,它明确地列出了字段.因此,在flatpages应用程序中注册后,您需要在某处取消注册(admin.site.unregister)并注册您自己的ModelAdmin.