2011-01-09 84 views
2

我有一个包含各种类型设置的表。我想在表单中以不同的方式显示和验证每个设置。例如,如果设置为整数或字符串。Django Dynamic Widget /表单字段表示

这是我的模型

class Setting(models.Model): 
    SETTING_TYPES = (
     (u'1', u'Decimal'), 
     (u'2', u'Integer'), 
     (u'3', u'String'), 
    ) 
    type = models..CharField(max_length=2, choices=SETTING_TYPES) 
    name = models.CharField(max_length=50, unique=True) 
    value = models.CharField(max_length=200) 

因此,如果类型为1我想限制形式录入和验证针对的事实,我很期待小数。但如果类型是3,我需要显示一个更大的条目形式,并根据预期字符串的事实进行验证。

几个地方,我可以用可能看到要做到这一点:

  1. 在自定义窗口小部件
  2. 通过重写BaseModelFormSet类使用上的init(http://snippets.dzone.com/posts/show/7936
  3. 改变字段属性自定义模板过滤器,将评估类型是什么,然后通过该设置类型的自定义模板手动呈现表单
  4. 将类型和值一起存储在jsonfield中,并使用诸如http://www.huyng.com/archives/django-custom-form-widget-for-dictionary-and-tuple-key-value-pairs/661/之类的内容来更改th e显示和验证设置值在一个地方..

有了选项1,我不确定我是否在'value'字段上使用自定义小部件,如果它能够访问'type '字段来确定如何表示'值'

我试过选项2,虽然我可以访问表单元素,但我无法访问表单值来确定设置的类型(也许它们没有绑定然而?)。我认为这条路线可能是simpliest但我需要访问形成价值观..

class BaseSettingFormset(BaseModelFormSet): 
    def __init__(self, *args, **kwargs): 
     super(BaseSettingFormset, self).__init__(*args, **kwargs) 
     for form in self.forms: 
      # here i would access the type value and then change the widget propeties below 
      if form.fields['type'] == 3: # DOESN"T WORK :(
       # change the widget and field properties 
       form.fields['value'].help_text='some text' 
       form.fields['value'].widget = CustomWidget() # or switch from decimal to string widgets.. 

def editProfile(request, strategy_id): 
    settingModelFormset = modelformset_factory(profile, formset=BaseSettingFormset) 

    ... retrieve the values and show them.. 

(同时发布这个我没有找到一个职位,可以让我在初始化过程中的窗体绑定,因此有机会获得值,请参阅django - how can I access the form field from inside a custom widget

选项3适用于显示字段,但不适用于验证任何数据。 我想我需要将它与选项2结合以在保存期间对其进行验证。

#Custom template filter 
@register.filter(name='show_setting') 
def show_setting(form): 
    setting = field_value(form['type']) # calls another function to retrieve value (works ok) 
    # render page using custom template that can alter the form to show a small field or text area etc. 
    # can also add js validations here.. (but no server validations) 
    if setting: 
     return render_to_string('setting-'+str(setting)+'.html', { 'form': form }) 

哪种方法最好(或者有其他方法),我该如何完成它? 或者我正在做这个错误的方式,有没有更多的djangoesc方式来解决我的问题?

回答

0

我相信你正在寻找的是一个custom validator传递到CharField的构造函数。

另一个可能更优雅的解决方案取决于具体情况,可能是让您自己的字段类扩展CharField并重载其验证代码。