Django Dynamic Widget / Form字段表示

时间:2011-01-09 20:14:11

标签: python django dynamic django-forms field

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

这是我的模特

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/之类的内容在一个地方更改设置值的显示和验证..
  5. 使用选项1,我不确定我是否在“值”字段上使用自定义窗口小部件,如果它能够访问“类型”字段以确定如何表示“值”

    我尝试了选项2,虽然我可以访问表单元素,但我无法访问表单值来确定设置的类型(可能它们还没有绑定?)。我认为这条路线可能是最简单的,但我需要访问表格值..

    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方法来解决我的问题?

1 个答案:

答案 0 :(得分:0)

我相信你要找的是传递给CharField构造函数的custom validator

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