如何覆盖Django模型字段中的这个方法
我正在尝试修改一个现有的Django Mezzanine设置,以便让我可以用Markdown写博客。Mezzanine有一个“核心”模型,其中的内容是用HtmlField来定义的,具体如下:
from django.db.models import TextField
class HtmlField(TextField):
"""
TextField that stores HTML.
"""
def formfield(self, **kwargs):
"""
Apply the class to the widget that will render the field as a
TincyMCE Editor.
"""
formfield = super(HtmlField, self).formfield(**kwargs)
formfield.widget.attrs["class"] = "mceEditor"
return formfield
问题出在mceEditor的widget.attrs["class"]上。我想的办法是对Blog对象的Content字段进行修改。
class BlogPost(Displayable, Ownable, Content):
def __init__(self, *args, **kwargs):
super(BlogPost, self).__init__(*args, **kwargs)
self._meta.get_field('content').formfield = XXX
我的问题是,我的Python技能还不足以用一个lambda函数来替换一个绑定的方法,并且这个lambda函数需要调用super
。
formfield是在管理后台需要创建一个字段以便在管理页面上显示时被调用的,所以我需要对它进行修改,以确保BlogPost的widget对象没有mceEditor这个类(我想在其他所有地方保留mceEditor)。
那么,如何编写这个替换函数呢?我很确定我可以用
setattr(self._meta.get_field('content'), 'formfield', method_i_dont_know_how_to_write)
2 个回答
1
我知道这个问题几个月前就有人回答过了,但为了防止其他人遇到同样的问题,Mezzanine现在提供了完全修改所见即所得(WYSIWYG)编辑器字段的功能。你可以在这里查看相关文档:
http://mezzanine.jupo.org/docs/admin-customization.html#wysiwyg-editor
1
你可以在管理员的方法 formfield_for_dbfield
中更改使用的表单字段:
class BlogAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
field = super(BlogAdmin, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'content':
field.widget = ....
field.widget.attrs['class'] = ...
return field
如果你真的想进行猴子补丁(也就是修改现有代码),可以这样做:
class BlogPost(Displayable, Ownable, Content):
def __init__(self, *args, **kwargs):
super(BlogPost, self).__init__(*args, **kwargs)
def formfield_new(self, *args, **kwargs):
# do here what you would like to do
return formfield
instancemethod = type(self._meta.get_field('content').formfield)
self._meta.get_field('content').formfield = instancemethod(formfield_new,
self, BlogPost)