2010-07-17 58 views
3

我有多個ModelForm類,每個代表不同的模型。我想要一個通用的'創建'函數,根據URL參數加載指定的模型表單。它可以動態加載模型這樣的:getModel等價於ModelForms?

model_name = 'TestModel' 
m = get_model('AppLabel', model_name) 

有誰知道我怎麼能實現ModelForms一樣的,是這樣的:

modelform_name = 'TestModelForm' 
f = get_form('AppLabel', modelform_name) 
if f.is_valid(): 
    ... 

我不能想辦法做到這一點使用通用視圖 - 它們需要傳遞ModelForm,而不僅僅是它的名字。如果我用get_model得到模型,然後將它傳遞給通用視圖,它將顯示一個表單,但我無法排除模型字段。

TIA任何提示

+0

或者有一個自定義視圖來處理您的url並在自定義視圖中獲取form_class,然後使用_class – Ashok 2010-07-17 03:47:42

回答

2

當你創建一個ModelForm它不會與它的模型的應用程序註冊。 (根據經驗和快速瀏覽源代碼)。

這裏有一些otheroptions我能想到的:在單一模塊中存在

  1. 所有ModelForm類:使用getattr基於字符串該模塊上。

  2. ModelForm的多種模式中傳播出來,你有形式合理(< 30)量: 創建一個從你期望的ModelForm類形式的字符串的字典映射。例如:

    from some_app.forms import FirstModelForm 
    from another_app.forms import SecondModelForm 
    from additional_app.forms import FirstModelForm as AdditionalAppFirstModelForm # Will allow for managing conflicting names easily. 
    
    form_mapping = { 
        'FirstModelForm': FirstModelForm, 
        'SecondModelForm': SecondForm, 
        'AdditionalAppFirstModelForm': AdditionalAppFirstModelForm, 
    } 
    
    request_form_class = request.POST.get('form_class') 
    f = form_mapping.get(request_form_class)(request.POST) 
    
    if f.is_valid(): 
        f.save() 
    
  3. 你處理很多形式:爲您的ModelForm創建一個基類,或在運行時更換BaseModelFormMetaclass。您必須處理諸如名稱衝突等問題,重複使用ModelForm s,以便自動「自動」處理Model,因此請準備好解決一些頭痛問題。如果你能把它拉下來,那將是相當不錯的。

個人(你可能會看到),我只是選擇#2。

+0

形式調用通用視圖。非常棒的答案,選項2完美地工作。謝謝! – 2010-07-17 19:01:00

+0

@Mike:你非常歡迎。記得從「Python的禪」('import this'):「顯式比隱式更好」。 #3將是一個需要很多「巫術」被認爲是接近明確的方式。此外,請確保在獲取表單類時添加一些錯誤檢查,並提出相應的「Http404」。它將爲您節省一些未來的麻煩。 – sdolan 2010-07-17 19:10:57

+0

謝謝,使用映射的方式是個好主意訣竅 – zhihong 2015-10-27 16:29:32

-1

另一種方法是用名爲forms的軟件包替換forms.py。然後,在該包中的__init__.py中,導入所有ModelForm

然後你可以使用sdolan的選項#1。

+0

這個答案沒有解決這個問題。問題是如何動態加載特定的表單類,給定一個模型名稱。 – 2015-06-08 12:57:16

+0

此外,這個問題在五年前成功回答。 – 2015-06-08 12:57:36