我有两个模型,一个是 Employee,另一个是 Asset,Asset 和 Employee 之间存在多对一关系。并且资产作为 StackedInline 字段添加到员工管理界面,无论如何我可以将资产设置为员工管理中的只读字段。
我的目的是显示员工当前在 Admin 中持有的所有资产,这样他就不会意外删除它。
我有两个模型,一个是 Employee,另一个是 Asset,Asset 和 Employee 之间存在多对一关系。并且资产作为 StackedInline 字段添加到员工管理界面,无论如何我可以将资产设置为员工管理中的只读字段。
我的目的是显示员工当前在 Admin 中持有的所有资产,这样他就不会意外删除它。
编辑:实际上,我认为这不适用于内联模型..
Django 将在 Django 1.1 中添加本机只读字段,该字段应该在 3 月中旬左右发布。
只读管理字段( http://www.djangosnippets.org/snippets/937/ )
此代码段将允许您在管理员中将字段设置为只读。
使用此代码并将其作为 ReadonlyAdmin 导入 admin.py。这是只读管理员的修改形式。
from django import forms
from django.utils.safestring import mark_safe
from datetime import datetime
class ReadOnlyWidget(forms.Widget):
def __init__(self, original_value, display_value):
self.original_value = original_value
self.display_value = display_value
super(ReadOnlyWidget, self).__init__()
def render(self, name, value, attrs=None):
if self.display_value is not None:
return unicode(self.display_value)
return unicode(self.original_value)
def value_from_datadict(self, data, files, name):
return self.original_value
#to make fields foreignkey readonly
class ReadOnlyAdminFields(object):
def get_form(self, request, obj=None):
form = super(ReadOnlyAdminFields, self).get_form(request, obj)
if hasattr(self, 'readonly') and obj is not None:
for field_name in self.readonly:
if field_name in form.base_fields:
if hasattr(obj, 'get_%s_display' % field_name):
display_value = getattr(obj, 'get_%s_display' % field_name)()
else:
display_value = None
if getattr(obj, field_name).__class__ in [unicode , long, int, float, datetime, list]:
form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name), display_value)
else:
form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name).id, display_value)
form.base_fields[field_name].required = False
return form
我不认为 django-admin 中有一个标志,请查看 Django 书的第 18 章了解更多详细信息,您需要手动破解模板
我认为也许您可以将自定义小部件添加到只是基本表单的字段,除了在所有元素上设置“禁用” - 我无法告诉您如何消除添加新记录的可能性。
如果您只想显示员工的资产,您可以更改默认的 django admin change_form.html。(您可能还想先禁用内联)
要覆盖默认管理模板,请将管理模板文件夹复制到本地 django 模板文件夹(setting.py 中的 ${TEMPLATE_DIRS})
而在change_form.html中,有这个块,
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
用于显示内联,在这里您可以做的是,将一些额外的信息,例如当前员工的资产列表,渲染到此模板,并将它们放在内联的原始位置上方。
现在的问题是:如何将这些额外信息呈现给这个模板?这可以通过覆盖员工管理模型中的 change_view() 函数来完成。
例如,在您的 admin.py
class EmployeeAdmin(admin.ModelAdmin):
...
def change_view(self, request, object_id, extra_context=None):
assets = Asset.objects.filter(employee=Employee.objects.get(id=object_id))
context_data = {'inlines': assets, }
return super(EmployeeAdmin, self).change_view(request, object_id, extra_context=context_data)
现在回到管理员的 change_form.html,使用模板标签显示来自 EmployeeAdmin 的 extra_context。
例如,
{% for inline in inlines %}
{{ inline }}
{% endfor %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
希望这会有所帮助,这是 django 1.2.4