1

我有两个模型,一个是 Employee,另一个是 Asset,Asset 和 Employee 之间存在多对一关系。并且资产作为 StackedInline 字段添加到员工管理界面,无论如何我可以将资产设置为员工管理中的只读字段。

我的目的是显示员工当前在 Admin 中持有的所有资产,这样他就不会意外删除它。

4

5 回答 5

3

编辑:实际上,我认为这不适用于内联模型..

Django 将在 Django 1.1 中添加本机只读字段,该字段应该在 3 月中旬左右发布。

只读管理字段( http://www.djangosnippets.org/snippets/937/ )

此代码段将允许您在管理员中将字段设置为只读。

于 2008-12-04T12:32:06.103 回答
2

使用此代码并将其作为 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
于 2009-07-03T06:58:30.510 回答
0

我不认为 django-admin 中有一个标志,请查看 Django 书的第 18 章了解更多详细信息,您需要手动破解模板

http://www.djangobook.com/en/beta/chapter18/

于 2008-12-04T09:44:25.287 回答
0

我认为也许您可以将自定义小部件添加到只是基本表单的字段,除了在所有元素上设置“禁用” - 我无法告诉您如何消除添加新记录的可能性。

于 2008-12-04T09:49:26.087 回答
0

如果您只想显示员工的资产,您可以更改默认的 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

于 2011-02-20T05:15:53.697 回答