2011-02-03 56 views
13

我有一個模型,Foo。它有幾個數據庫屬性和幾個基於多種因素組合計算的屬性。我想將這些計算出的屬性呈現給用戶,就好像它們是數據庫屬性一樣。 (支持因素將被改變以反映用戶輸入。)有沒有辦法用Django管理界面來做到這一點?Django:在管理界面中僞造一個字段?

+0

你想在管理員更改列表或表單中顯示它們嗎? – 2011-02-03 20:45:51

+0

@lazerscience我不確定管理員更改列表是什麼。絕對是這種形式。 – 2011-02-03 21:07:36

+0

如果您希望他們在表單中顯示(顯示爲不可編輯),並且它們可在模型中用作方法,則可以將文件「change_form.html」複製到您的$ {TEMPLATE_ROOT}/admin/APPNAME/MODELNAME/change_form.html並將其編輯爲您心中的內容。 – 2011-02-03 21:37:48

回答

30

我建議你爲Foo(FooAdminForm)子類化一個模型表單,以添加你自己的字段,而不是由數據庫支持。您的自定義驗證可以駐留在ModelForm的clean_*方法中。

裏面的FooAdmin你的請求時,Foo實例和表單數據的save_model方法,所以你可以保存實例之後,做前/後的所有數據處理。

下面是一個自定義表單模型Django管理註冊的例子:

from django import forms 
from django.db import models 
from django.contrib import admin 


class Foo(models.Model): 
    name = models.CharField(max_length=30) 


class FooAdminForm(forms.ModelForm): 
    # custom field not backed by database 
    calculated = forms.IntegerField() 

    class Meta: 
     model = Foo 


class FooAdmin(admin.ModelAdmin): 
    # use the custom form instead of a generic modelform 
    form = FooAdminForm 

    # your own processing 
    def save_model(self, request, obj, form, change): 
     # for example: 
     obj.name = 'Foo #%d' % form.cleaned_data['calculated'] 
     obj.save() 


admin.site.register(Foo, FooAdmin) 

提供了自定義字段的初始值根據實例數據

(我不知道這是否是最好的解決方案,但它應該工作。)

當數據庫中現有模型實例的模型se被構造,它通過這個實例。因此,在FooAdminForm的__init__中,可以根據實例數據更改字段屬性。

def __init__(self, *args, **kwargs): 
     # only change attributes if an instance is passed    
     instance = kwargs.get('instance') 
     if instance: 
      self.base_fields['calculated'].initial = (instance.bar == 42) 
     forms.ModelForm.__init__(self, *args, **kwargs) 
1

可以使用@property裝飾你的模型(的Python> = 2.4):

class Product(models.Model): 

    @property 
    def ranking(self): 
     return 1 

「排名」 然後可以在list_display使用:

class ProductAdmin(admin.ModelAdmin): 
    list_display = ('ranking', 'asin', 'title') 
4

這很容易足以讓任意數據顯示在更改列表中或使字段以下列格式顯示:list_display任意使用實際模型屬性或在模型或modeladmin上定義的方法,並且您c一個子類forms.ModelForm添加您想要更改表單的任何字段類型。

將兩者結合起來會更困難/不可能,即在更改列表上有任意一條數據,您可以通過指定list_editable就地進行編輯。 Django似乎只接受與數據庫字段相對應的真正模型屬性。 (即使在模型定義中使用@property的方法也是不夠的)。

有沒有人找到一種方法來編輯實際上沒有出現在模型右側的字段從更改列表頁面?