2012-05-04 83 views
2

我們有一個包含models.py的應用程序,其中包含n個no。的類繼承基類。我們想創建一個表單,它動態地從用戶n中保存數據庫中的值,但問題是我們想用django表單域而不是django模型表單。如何在Django中使用表單域映射模型字段

因爲我們知道有一些領域在Django的形式缺少如PositiveIntegerField,CommaSeparetedIntegerFields等,我們怎樣才能做到這一點使用Django的表單字段?
如果我們在shell中編寫follwing代碼。

from djnago.db import models 
mvar = models.PositiveIntegerFields() 

from django import forms 
fvar = forms.PositiveIntegerFields() 
AttributeError: 'module' object has no attribute 'PositiveIntegerField' 

forms.py

from django import forms 

class ContextForm(forms.Form): 
    def __init__(self, rdict, *args, **kwargs): 
     super(ContextForm, self).__init__(*args, **kwargs) 
     for key in rdict.keys(): 
      self.fields['%s' % str(key)] = getattr(forms,rdict.get(key))() 

rdict = {'address': 'CharField','phone': 'CharField', 'Salary': 'PositiveIntegerField','first name': 'CharField','last name':'CharField'} 
+0

爲什麼不使用'ModelForm'並堅持使用standart Form?雖然您想要的所有內容都已通過'ModelForm'提供給您,但您必須有一個非常好的理由不要使用它。 – FallenAngel

+0

我們可以動態創建ModelForm嗎? –

+0

我敢肯定,我們可以 – okm

回答

2

查看源,所有的現場確實是調用默認的表單字段與關鍵字參數:min_value

class PositiveIntegerField(IntegerField): 
    description = _("Positive integer") 

    def get_internal_type(self): 
     return "PositiveIntegerField" 

    def formfield(self, **kwargs): 
     defaults = {'min_value': 0} 
     defaults.update(kwargs) 
     return super(PositiveIntegerField, self).formfield(**defaults) 

因此你正在尋找的是僅僅

from django import forms 
fvar = forms.IntegerField(min_value=0) 
fvar.clean(-1) 
# ValidationError: [u'Ensure this value is greater than or equal to 0.'] 

至於CommaSeparatedIntegerField,它看起來像一些django.core.validators.validate_comma_separated_integer_list傳入的一個CharField

f = forms.CharField(validators=[django.core.validators.validate_comma_separated_integer_list]) 
f.clean('1,2,3') 

所有這樣做是確保傳入的字符串是'^[\d,]+$'。該領域甚至沒有進行任何python轉換......如果僅僅驗證表單輸入,它似乎並沒有節省太多時間。的確,有評論說「可能轉向貢獻」。同意..


決定看看這個樂趣。這是一個ModelForm生成器,用新字段覆蓋模型字段......它尚未處理kwargs。這只是我能想到的第一種方法,不需要查看模型生成本身。它構造了一個修改表單/之後/初始化的常規ModelForm

MODEL_FIELD_MAP = { 
    models.IntegerField: forms.CharField, 
    # change all IntegerField to forms.CharField 
} 

def modelform_generator(mymodel): 
    class MyModelForm(forms.ModelForm): 
     class Meta: 
      model = mymodel 
     def __init__(self, *args, **kwargs): 
      super(MyModelForm, self).__init__(*args, **kwargs) 
      for name, form_field in self.fields.items(): 
       try: 
        model_field = self._meta.model._meta.get_field_by_name(name)[0] 
        # is this a model field? 

        field_override = MODEL_FIELD_MAP.get(model_field.__class__) 
        # do we have this model field mapped to a form field? 

        if field_override: 
         self.fields[name] = field_override() 
         # set the form field to the target field class 

       except models.FieldDoesNotExist: 
        pass 
    return MyModelForm 
+0

取代這個解決方案,還有另一種方法來映射模型字段來形成字段因爲創建自定義字段是好的,但是怎麼樣休息字段不是Django形式。而且我們正在創建動態表單,這些表單應該與模型字段映射 –

+3

@SweetGirl不是那個ModelForms的用途嗎? –

+0

我們可以動態創建模型嗎? –

相關問題