2

我们有一个包含 models.py 的应用程序,其中包含 n 号。继承基类的类。我们想要创建从用户 n 保存在 db 中的动态获取值的表单,但问题是我们想要使用 django 表单字段而不是 django 模型表单。

我们知道 django 表单中缺少一些字段,例如PositiveIntegerField、CommaSeparetedIntegerFields等。我们如何使用 django 表单字段来实现这一点?
如果我们在 shell 中编写以下代码。

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

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

表格.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'}
4

1 回答 1

1

查看源代码,该字段所做的只是使用关键字参数调用默认表单字段: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,它看起来像CharField带有一些django.core.validators.validate_comma_separated_integer_list传入的。

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

所有这些都是确保传入的字符串是'^[\d,]+$'. 该字段甚至不进行任何 python 转换......如果只是验证表单输入,它似乎并没有真正节省很多时间。事实上,有一条评论说“可能会转向贡献”。同意..


决定看看这个好玩。这是一个ModelForm用新字段覆盖模型字段的生成器......它还没有处理 kwargs。这只是我能想到的第一种方法……无需研究模型生成本身。它构造了一个ModelForm修改表单 /after/ 初始化的正则。

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
于 2012-05-04T07:07:34.803 回答