2008-12-04 59 views
1

我有兩種模式,一種是員工,另一種是資產,資產和員工之間有多對一的關係。資產被添加爲StackedInline字段到員工管理界面,無論如何,我可以使資產作爲員工管理中的只讀字段。Django外鍵只讀

我的意圖是顯示員工當前持有的所有資產,以便他不會意外刪除它。

回答

0

我想也許你可以添加一個自定義小部件到只是一個基本形式的字段,除了在所有元素上設置'disabled' - 我不能告訴你如何刪除添加新記錄的可能性。

3

編輯:其實,我不認爲這會爲在線模式工作..

Django會被添加在Django 1.1原生只讀字段,它應該圍繞三月中旬發佈。

Read Only Admin Fieldshttp://www.djangosnippets.org/snippets/937/

這個片段將允許您設置字段爲只讀的管理員。

+0

謝謝你,你讓我很快樂! – 2011-11-29 17:50:41

2

使用此代碼 並將它作爲ReadonlyAdmin導入到admin.py中。這是readonly admin的修改形式。

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 
+0

請小心使用此解決方案。嘗試檢查字段是否是對象,而不是檢查該字段不是對象。 – 2012-02-01 15:00:59

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 %} 

這是用來顯示內聯,和則可以在做什麼在這裏,使一些額外的信息,如當前員工資產的清單,這個模板,並將它們放置在內聯原始位置的上方。

現在的問題是:如何將此額外信息呈現給此模板?這可以通過重寫Employee的管理模型中的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