Django管理界面:覆盖显示字段值

8
我有以下模型:
class Model(models.Model):

    creator = models.ForeignKey(User,related_name='com_creator',on_delete=models.SET_NULL, blank=True, null=True)
    username = models.CharField(max_length=60,default="")
    created = models.DateTimeField(auto_now_add=True)
    body = models.TextField(max_length=10000,default=" ")
    subtype = models.CharField(_("SubType"),max_length=100)
    typ = models.CharField(_("Type"),max_length=50)
    plus = models.ManyToManyField(User,related_name='com_plus', verbose_name=_('Plus'), blank=True)
    is_anonymous = models.BooleanField(_('Stay Anonymous'), blank=True, default=False)

typ和subtype中的值是代码,例如: "6_0_p",因为原始值过长,所以我使用代码和字典将其转换为人类可读的形式。

问题: 我如何在Django管理页面拦截这些值并将它们翻译为人类可读的形式?

这是我到目前为止尝试过的:

class ModelAdmin(admin.ModelAdmin):
    model = Model
    extra = 1
    exclude = ("username","creator","plus" ) 
    readonly_fields = ('subtype','typ','is_anonymous','created')
    fields = ('body','subtype','typ')

    def typ(self, obj):
        self.typ = "ppp"
        obj.typ = "ppp"
        return "pppp"

我尝试过返回对象、self和其他值。我还尝试过不使用可调用函数,只声明“typ='xxx'”来设置值。但是都没有成功。我可能不理解这整个过程的工作原理...如果有任何想法,请告诉我。
3个回答

8

我在我的示例代码中确实有这种方法。它没有起作用。 - Stefan
4
如果你的数据库字段与方法名称相同,这个方法将无法工作。请将方法命名为与现有字段不同的其他名称,并将其放在readonly_fields中。复制上面的示例并测试它是否可行。在readonly_fields的末尾添加my_custom_field,并添加一个同名的方法以查看其效果。 - Yuji 'Tomita' Tomita
非常感谢 @Yuji'Tomita'Tomita 的澄清 - 现在我如何将返回值变成 HTML 呢?我想要显示一个列表。 - Lenka Pitonakova
@Elendurwen 请看这里 https://dev59.com/X3A75IYBdhLWcg3wbojM -- 取决于版本。 - Yuji 'Tomita' Tomita

5
我认为你的代码不起作用是因为方法名与字段名相同。
你需要更改字段名,比如在字段元组中使用“_typ”,然后添加一个名为“_typ”的方法,该方法返回任何东西或一些对象属性。
例如:
class ModelAdmin(admin.ModelAdmin):
    model = Model
    extra = 1
    exclude = ("username","creator","plus" ) 
    readonly_fields = ('subtype','typ','is_anonymous','created')
    fields = ('body','subtype','_typ')

    def _typ(self, obj):
        return "pppp"

现在显示:"FieldError:未知字段" - Stefan
1
Yuji 给我更详细地解释了一下。你的回答在技术上也是正确的,但我从他的努力中理解了它。非常感谢你。 - Stefan

2
在 Django 4 及以上版本中,您可以轻松地添加自定义(只读)字段,如下所示:
class FooAdmin(admin.ModelAdminAbstractAdmin):
    readonly_fields = [
        '_dynamic_field',
    ]
    fieldsets = [
        ('Form', {
            'fields': (
                '_dynamic_field',
            ),
            'classes': ('form-group',)
        }),
    ]

    def _dynamic_field(self, obj=None):
        if obj is not None:
            return 'Bar'
        return "Foo"

    # to change the label
    _dynamic_field.__name__ = "Dynamic field label"

正如您所看到的,该字段需要在readonly_fieldsfieldsets中。


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