如何在Django ModelAdmin的字段集中调用模型方法?

17
我希望在管理表单上显示一个嵌入式地图,当数据库中已存在数据时。我有以下代码:
models.py
class Address(models.Model):
    address = models.CharField()

    def address_2_html(self):
        if self.address:
            # Return html for an embedded map using the entered address.
            return embedded_map_html
        else:
            return ''
    address_2_html.allow_tags = True

管理.py

class AddressAdmin(admin.ModelAdmin):
    fieldsets = [(label, {'fields': ['address','address_2_html']}),]

这个不起作用。我收到了一个错误:

'AddressAdmin.fieldsets[1][1]['fields']' refers to field 'address_2_html' that is missing from the form.

我尝试的另一件事是使用“字段集”的“描述”选项,但是,“address_2_html”在AddressAdmin的范围内无法访问。我成功地使用“描述”嵌入了一个静态地图,这很酷,但不够酷。

2个回答

30

像这样(从记忆中):

class AddressAdmin(admin.ModelAdmin):
    fieldsets = [(label, {'fields': ['address','address_2_html']}),]
    readonly_fields = ['address_2_html']

    def address_2_html(self, obj):
        return obj.address_2_html()
    address_2_html.allow_tags = True
    address_2_html.short_description = 'Address display'

1
使用这个解决方案时,我遇到了以下错误:“AddressAdmin.fieldsets[0][1]['fields']”引用了表单中不存在的字段“address_2_html”。 - nu everest
2
如果“display_map3”与你的示例中的“address_2_html”等效,则是否像我的示例中一样将“display_map3”放入“readonly_fields”中? - Etienne
1
它在我的“字段集”中有效。你的代码其他地方有问题。 - Etienne
11
添加 readonly_fields = ['address_2_html'] 选项有所帮助。现在它可以正常工作了。我比起重写 get_fieldsets() 更喜欢你的解决方案。谢谢。 - nu everest
2
对于Django 1.9及以上版本,请使用return format_html(...)代替.allow_tags = True,因为后者已被弃用(参见https://docs.djangoproject.com/en/1.9/ref/contrib/admin/)。 - shad0w_wa1k3r
显示剩余2条评论

2
通过重写get_fieldsets()方法解决的问题,因为get_fieldsets()方法允许访问模型对象Address。
def get_fieldsets(self, request, obj=None):
    fs = [
        (self.label,  {'fields': ['address',]}),
        ('Map', {'fields': [], # required by django admin
                'description':obj.address_2_html(),
         }),
    ]
    return fs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接