2015-11-03 98 views
0

是否可以构建一个自定义模型字段/窗口小部件组合,该组合显示值但不会将任何内容写回数据库?我只会在管理员的表单中使用这个小部件。创建仅显示(不可编辑)的Django管理员字段

我写了自己的字段,它覆盖了formfield()方法来声明它自己的窗口小部件类。它显示就好了,但只要“保存”按钮被点击的管理员,我得到验证错误:

This field is required. 

这是有道理的,考虑到我的窗口小部件没有呈现出一种形式领域。但是,我想要做的是基本上从更新过程中删除该字段:无论何时在管理中使用,它都不应该在SQL UPDATE中提及。

这可能吗?

下面的代码的素描时,我到目前为止有:

class MyWidget(Widget): 
    def render(self, name, value, attrs=None): 
     if value is None: 
      value = "" 
     else: 
      # pretty print the contents of value here 
      return '<table>' + ''.join(rows) + '</table>' 

class MyField(JSONField): 
    def __init__(self, *args, **kwargs): 
     kwargs['null'] = False 
     kwargs['default'] = list 
     super(MyField, self).__init__(*args, **kwargs) 

    def formfield(self, **kwargs): 
     defaults = { 
      'form_class': JSONFormField, 
      'widget': MyWidget, 
     } 
     defaults.update(**kwargs) 
     return super(MyField, self).formfield(**defaults) 

更新1:用例是外地代表的审计日志。在内部,它会定期写入。然而,管理员永远不需要写入它,它只需要以非常可读的格式呈现出来。

我没有在应用程序中使用任何其他的ModelForms,所以管理员是唯一的窗体用户。我不想在管理类本身上实现这种行为,因为这个字段将在各种模型中重用,并且总是应该以相同的方式运行。

+0

作为一种临时解决方案,我已经为我的窗口小部件渲染器添加了一个隐藏字段,但这只是感觉不对:现在我通过浏览器发送序列化的字段内容,然后将它们反序列化,而不仅仅是从保存操作中删除这一个字段。 –

回答

1

我可能对你想要的有点困惑,但你可能想看看模型属性。这是我目前的项目的一个例子。

代码模型里面:

class Textbook(models.Model): 
    #other fields 

    @property 
    def NumWishes(self): 
     return self.wishlist_set.count() 

然后,你可以将其显示在管理页面上。

class Textbook_table(admin.ModelAdmin): 
    fields = ["""attributes that are saved in the model"""] 
    list_display = ("""attributes that are saved in the model""", 'NumWishes'') 

因此,现在我可以在管理页面中显示NumWishes,但不需要使用该模型创建NumWishes。

+0

那么,我需要它来支持一个字段,因为它是存储在数据库中的实际数据,并且会被我的应用程序修改。我只想在管理员中以一种额外的可读格式呈现它,并且我从不想在管理员中对其进行编辑。 –

+0

嗯,我从来没有这样做过。抱歉! – Programmingjoe

5

有多种方法可以在管理页面中创建只读字段。您对数据库存储的要求有点模糊,所以我会通过选项。

你必须在admin.py先注册一个AdminModel:

from django.contrib import admin 
from yourapp.models import YourModel 

class YourAdmin(admin.ModelAdmin): 
    pass 

admin.site.register(YourModel, YourAdmin) 

现在你可以在不同的行为,将其添加。例如,您可以添加在编辑显示的字段列表/添加页面:

class YourAdmin(admin.ModelAdmin): 
    fields = ['field1', 'field2'] 

这可能是示范田,示范性或模型方法的名称。方法显示为只读。

如果你想有一个字段只读明确补充一点:

​​

然后,你必须完全通过添加一个方法具有相同名称覆盖字段的显示选项。你甚至不会需要一个模型字段/方法使用该名称,则:

class YourAdmin(admin.ModelAdmin): 
    fields = ['field1', 'field2'] 
    readonly_fields = ['field2'] 

    def field2(self, obj): 
     return '*** CLASSIFIED *** {}'.format(obj.field2) 

随着django.utils.safestring.mark_safe可以返回HTML代码。

管理员的所有其他选项都可用,但小部件配置除外,因为它仅适用于可写字段。

+0

感谢您的详细的概述,很好的总结不同的选项!然而,我希望将这种行为与字段类型本身相关联,因为我打算在各种模型中重用它,它将仅由应用程序(它基本上是一个审计日志)写入,但始终是只读的管理员。 –

+0

这实际上是管理模型配置从数据模型移动到管理模型的原因。但是,您可以通过检查字段的类型来对任何模型字段进行子类化,并从模型中动态生成'readonly_fields'。 –

相关问题