基于远程相关模型的Django表格验证

时间:2016-12-16 19:58:57

标签: python django forms validation django-forms

我对Django仍然缺乏经验,但我坚持这个问题。我得到了一个几乎已经完成的项目,父母可以在这个项目中填写对孩子的评估,然后研究人员可以使用Django和Postgresql收集和存储这些数据。有两个相关模型位于两个不同的应用程序中,它们都相互关联。一个"乐器" (测试类型)可以有多个研究,而这些研究又可以有多个参与者。我制作了一幅画得很糟的图像来描述我的意思。

有一种形式,BackgroundForm,它收集人口统计信息(年龄,出生体重等)。然后将该数据存储在具有参与者管理ID的模型BackgroundInfo中。我有问题使表单验证更灵活。某些工具(测试)是针对特定年龄的,我不知道如何将这些信息一直提供给BackgroundForm验证,因为它位于几个关系之外。有没有办法启用表单验证,验证取决于位于几个关系的模型的属性?

Map of Django site

cdi_forms / forms.py

class BackgroundForm(BetterModelForm):
    age = forms.IntegerField()
    sex = forms.ChoiceField(choices=(('M', 'Male'), ('F', 'Female'), ('O', 'Other')), widget=forms.RadioSelect)

    def clean(self):
        cleaned_data = super(BackgroundForm, self).clean()
        if cleaned_data.get('age') == '':
            self.add_error('age', 'Please enter your child\'s DOB in the field above.')

    class Meta:
        model = BackgroundInfo
        exclude = ['administration']

cdi_forms / models.py

class BackgroundInfo(models.Model):
    administration = models.OneToOneField("researcher_UI.administration")
    age = models.IntegerField(verbose_name = "Age (in months)")
    sex = models.CharField(max_length = 1, choices = (('M', "Male"), ('F', "Female"), ('O', "Other")))

researcher_UI / models.py

class administration(models.Model):
    study = models.ForeignKey("study")
    subject_id = models.IntegerField()

class study(models.Model):
    researcher = models.ForeignKey("auth.user")
    name = models.CharField(max_length = 51)
    instrument = models.ForeignKey("instrument")

class instrument(models.Model):
    name = models.CharField(max_length = 51, primary_key=True)
    language = models.CharField(max_length = 51, blank = True)
    min_age = models.IntegerField(verbose_name = "Minimum age", null = True)
    max_age = models.IntegerField(verbose_name = "Maximum age", null = True)

1 个答案:

答案 0 :(得分:0)

没关系!我做了一些搜索,我找到了这个page。基本上,我在views.py中抓取了我想要的参数并将它们传递给我的表单。

<强> cdi_forms / views.py

def background_info_form(request, hash_id):
    administration_instance = administration.objects.get(url_hash = hash_id) # Each test has it's own URL identifier
    min_age = administration_instance.study.instrument.min_age
    max_age = administration_instance.study.instrument.max_age
    ...
    background_form = BackgroundForm(request.POST, instance = background_instance, min_age = min_age, max_age = max_age)

<强> cdi_forms / forms.py

class BackgroundForm(BetterModelForm):
    age = forms.IntegerField()
    ...
    def __init__(self, *args, **kwargs):
        self.min_age = kwargs.pop('min_age', None)
        self.max_age = kwargs.pop('max_age', None)
        super(BackgroundForm, self).__init__(*args, **kwargs)
    ...
    def clean(self):
        #Now I can compare my age field to self.min_age and self.max_age