为formset中的字段创建动态标签

时间:2012-09-17 21:21:50

标签: django django-forms formsets

我的表格如下

class InstructorCourseCertificationForm(forms.Form):
    Course = forms.BooleanField()
    SubjectExpert = forms.BooleanField(label='Subject Expert')

我需要创建这些的formset,并根据我的课程列表动态设置Course字段的标签。

1 个答案:

答案 0 :(得分:0)

根据我的经验,我需要拥有动态字段,我通常最终将数据存储在数据库中,然后根据数据库中的数据生成动态表单。换句话说,我不创建基于forms.Form的类,我稍后会自定义,但是我使用python的type函数从头开始创建一个类。

我认为这可能在一个例子中更清楚。假设您有一个模型Course,其中包含name字段:

class Course(models.Model):
    name = models.CharField(max_length=64)

那么您可以通过向模型添加方法从头开始创建表单:

class Course(models.Model):
    ...
    def certificate_form_class(self):

        # assuming the name can only have spaces
        # if not, then more normalizing has to be done
        form_name = self.name.title().replace(' ', '')

        bases = (forms.Form,)

        fields = {
            'Course': forms.BooleanField(label=self.name),
            'SubjectExpert': forms.BooleanField(label='Subject Expert')
        }

        form_class = type(form_name, bases, fields)

        return form_class

然后你可以按如下方式使用它:

course = Course.objects.get(...)
certificate_form_class = course.certificate_form_class()
certificate_form = certificate_form_class()
# use it as a regular form

有人可能会争辩说,此时您正在混合表单和模型,在这种情况下,您可以在forms.py中创建一个辅助函数,它将采用Course模型的一个实例,然后创建一个证书表格不在外面。但无论哪种方式,这个想法都是一样的。

但有一点需要注意的是,在这一点上,您无法保证字段按顺序排列。在这种情况下,您应该使用OrderedDict中的collections代替dict{})来定义字段。

不确定此方法与FormSets的效果如何,但也许它可以为您提供一些想法。