2016-04-27 29 views
1

在Django中创建了一个完整的工作表单 - 但是当我尝试定义一个函数来提高自定义form.ValidationError时,它会中断。Django self.cleaned_data问题。

# importing form modules 

from django import forms 
import re 

# define the forms 

class single_input(forms.Form): 

    CHROMOSOMES = (

        ('1' , '1'), 
        ('2' , '2'), 
        ('3' , '3'), 
        ('4' , '4'), 
        ('5' , '5'), 
        ('6' , '6'), 
        ('7' , '7'), 
        ('8' , '8'), 
        ('9' , '9'), 
        ('10' , '10'), 
        ('11' , '11'), 
        ('12' , '12'), 
        ('13' , '13'), 
        ('14' , '14'), 
        ('15' , '15'), 
        ('16' , '16'), 
        ('17' , '17'), 
        ('18' , '18'), 
        ('19' , '19'), 
        ('20' , '20'), 
        ('21' , '21'), 
        ('22' , '22'), 
        ('23' , '23'), 
        ('X' , 'X'), 
        ('Y ' , 'Y') 

        ) 

    def clean_testname(self): 

     print self.cleaned_data 

     testname  = self.cleaned_data['testname'] 
     genome_pos = self.cleaned_data['genome_pos'] 


     if (not re.match(r"^\w+$", testname)): 

      raise forms.ValidationError(

       "Test name is only allowed letter's number's and _'s ." 
       "NO spaces or funny things that involve the shift button" 
       ) 

     if (not re.match(r"^\s+$", genome_pos)): 

      raise forms.ValidationError(

       "Genome position is only allowed numbers and -'s" 
       "NO spaces, letter or funny things that involve the shift button" 

       ) 


     return cleaned_data 


    testname = forms.CharField (label='testname', max_length=100) 
    chromosome = forms.ChoiceField(label='chromosome', choices = CHROMOSOMES , required = True) 
    genome_pos = forms.CharField (label='genome_pos', max_length=15) 

的问题是只需要第一个表单域cleaned_data所以print cleaned_data从上面的代码看起来像:

{'testname': u'ssss'} 

Wheras如果我注释掉整个clean_testname功能我得到一个工作输出

{'genome_pos': u'xxx', 'testname': "name", 'chromosome': u'1'} 

回答

3

的问题是,你正在试图清理testnamegenome_pos字段在clean_testname方法中。

您应该清除testname字段中的clean_testname方法和genome_pos字段中的clean_genome_pos方法。

如果你想validate fields that depend on each other,那么这属于clean方法。在这种情况下,它看起来并不需要clean方法,因为字段名似乎并不依赖于对方。

class SingleInput(forms.Form): 
    # It would be better to name the form SingleInput rather than single_input 

    def clean_testname(self): 
     test_name = self.cleaned_data['testname'] 
     # validate testname, raise ValidationError if necessary. 
     # you can't access any other fields from self.cleaned_data here 
     return testname 

    def clean_genome_pos(self): 
     test_name = self.cleaned_data['genome_pos'] 
     # validate genome_pos, raise ValidationError if necessary. 
     # you can't access any other fields from self.cleaned_data here 
     return genom_post 

    def clean(self): 
     cleaned_data = super(SingleInput, self).clean() 

     # you need to handle case when the fields do not exist in cleaned_data 
     testname = cleaned_data.get('testname') 
     genome_pos = cleaned_data.get('genome_pos') 

     if testname and genome_pos: 
      # do any checks that rely on testname *and* genome_pos, and 
      # raise validation errors if necessary 
      ... 

     return cleaned_data 

你的情况的另一种选择是使用RegexField而不是自定义清理方法。

class SingleInput(forms.Form): 
    testname = forms.RegexField(
     label='testname', 
     max_length=100, 
     regex=r"^\w+$", 
     message="<error message>", 
    ) 
    ... 
+0

它看起来并不像这两个值的验证是相互依赖的。有人可以在他们自己的'clean_ '方法中写入这些验证吗? – AKS

+0

我最初确实考虑过这个问题,为什么没有将完整的表单数据传递给clean ..... n ...函数虽然在我的理解中,我最初要求清理的所有数据?? – user3234810

+0

你不能指望'clean_testname'方法中的'genome_pos',因为'genome_pos'字段可能还没有被清除。如果你想要所有的'clean_data',你需要用'clean'来完成。 – Alasdair