2010-01-26 45 views
10

創建flatpage時,我希望用戶從預定義的列表中選擇一個模板。爲了保持Flatpage模式不變,我更喜歡ChoiceFieldModelChoiceField(後者提供模板的PK,但我需要爲TEMPLATE_NAME字段名):字段和base_fields - Django

class NewFlatpageForm(FlatpageForm): 

    template_name = forms.ChoiceField(choices = []) 
    def __init__(self, *args, **kwargs): 
     self.base_fields['template_name'].choices = ProjectTemplate.objects.values_list('path', 'name') 
     super(NewFlatpageForm, self).__init__(*args, **kwargs) 

我重寫__init__或者Django的在填充的選擇服務器啓動,然後不更新列表。

我沒有任何管理員經驗,但在不使用管理員時,我使用fields屬性做了類似的操作。但在這種情況下,我得到一個異常,告訴fields不是表單的屬性。 __dict__告訴我有一個base_fields屬性並使用它的作品。那麼,爲什麼在這裏使用base_fields,爲什麼fields不存在,最後我在做些什麼hacky?

回答

11

fields不存在,直到你叫super。所以只需交換行的順序,以便super排在第一位。

+0

謝謝Daniel .. – shanyu 2010-01-26 16:51:27

8

從我自己的經驗中得到的一個教訓:修改基本字段意味着您的修改「永遠」(直到python退出)。在你的情況下,這可能不是問題,因爲你始終使用相同的字段名稱,並且您正在使用ProjectTemplate中的賦值替換它的值...

在我的情況中,我想根據參數完全不同的字段在構造函數中。由於我的字段名稱通常是不同的,每次我實例化一個表單時,我添加了新的字段,但並沒有消除上一次的字段。

通過調用超早(如下所示),然後讓我的動態變化,以self.fields而不是self.basefields,我是能夠消除領域不斷增長的名單的問題。它現在非常有意義,但我並不熟悉所有的語法細節,並且正在黑客入侵,而不是先嚐試理解它。

3

除了Joe Germuska。如果您確實需要根據請求更改表單,則可以使用深層複製來確保沒有任何內容被引用更改:

def get_form(self, request, obj=None, **kwargs): 
    form = super(ResourceAdmin, self).get_form(request, obj, **kwargs) 
    form = copy.deepcopy(form) 

    if obj: 
     form.base_fields['email'] = EmailField(initial=obj.user.email) 
    if not request.user.is_superuser: 
     form.base_fields['user'].widget = HiddenInput(attrs={'class': 'hide_form_row'}) 

    return form