2017-06-25 17 views
2

我試圖進行表單驗證,以便某些字段只接受某些類型的輸入,例如名稱只接受字母和電話號碼,只接受10個數字。我試圖使一個驗證的名字,如下圖所示:如何在Django中進行表單驗證

#forms.py 

class StudentForm(forms.ModelForm): 
# STEP 1 FORM 
    student_id = forms.CharField(max_length=128, label="Student ID") 
    first_name = forms.CharField(max_length=128, label="First Name", widget=forms.TextInput(attrs={'class': 'form-control'})) 
    last_name = forms.CharField(max_length=128, label="Last Name") 
    ssn = USSocialSecurityNumberField(widget=forms.TextInput(attrs={'class': 'form-control'}), label="SSN", help_text="Format: xxx-xx-xxxx") 
    gender = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control'}), label="Gender", choices=GENDER_CHOICES) 
    dob = forms.DateField(widget=forms.DateInput(attrs={'class': 'form-control'}), label="Date of birth", help_text="Format: yyyy-mm-dd") 
    contact_number = forms.CharField(max_length=128, label="Contact number") 
    address = forms.CharField(max_length=128, label="Address") 
    city = forms.CharField(max_length=128, label="City") 
    state = forms.ChoiceField(choices=STATE_CHOICES, initial="NJ", label="State") 
    zipcode = USZipCodeField(label="Zipcode") 
    country = forms.ChoiceField(choices=countries, label="Country", initial="US") 
    home_phone = forms.CharField(max_length=128, label="Home phone") 
    cell_phone = forms.CharField(max_length=128, label="Cell phone") 
    email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'}), max_length=254, validators=[validate_email], label="Email") 
    background = forms.ChoiceField(choices=BACKGROUND_CHOICES, label="Background") 
    location = forms.ChoiceField(choices=LOCATION_CHOICES, initial="south_plainfield", label="Location") 
    workforce = forms.ChoiceField(choices=WORKFORCE_CHOICES, initial="--", label="Workforce") 
    source = forms.ChoiceField(choices=SOURCE_CHOICES, initial="individual", label="Source") 
    refer_by = forms.ChoiceField(choices=REFER_BY_CHOICES, initial="no refer", label="Refer by") 
    last_status = forms.ChoiceField(choices=LAST_STATUS_CHOICES, initial="followup", label="Last status") 
    newsletter = forms.BooleanField(widget=forms.CheckboxInput(), label="Newsletter", required=False) 
    created_by = forms.CharField(max_length=128, label="Created by") 
    date = forms.DateField(widget=forms.DateInput(attrs={'class': 'form-control'}), label="Date", help_text="Format: yyyy-mm-dd") 
    notes = forms.CharField(widget=forms.Textarea(attrs={'class': 'form-control'}), required=False, label="notes", help_text="less than 1000 characters") 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     first_name = cleaned_data.get('first_name') 

     if first_name.isalpha == False: 
      raise forms.ValidationError('Please enter a real name.') 
     elif first_name[0].isupper() == False or first_name[1:].isupper() == True: 
      raise forms.ValidationError('Please capitalize properly') 
     else: 
      cleaned_data['first_name'] = first_name 

     return cleaned_data 

    class Meta: 
     model = Student 
     fields = ('student_id', 'first_name', 'last_name', 'ssn', 'gender', 'dob', 'contact_number', 'address', 'city', 'state', 'zipcode', 'country', 'home_phone', 'cell_phone', 'email', 'background', 'location', 'workforce', 'source', 'refer_by', 'last_status', 'newsletter', 'created_by', 'date', 'notes') 

然而,提交表單的時候,它完全忽略它和我的數據庫瀏覽器顯示,隨着一個數字的名稱可以接受的。有沒有我寫錯了,或者我必須改變其他地方的一些代碼,除了forms.py?我覺得如果我能解決這個問題,其他人應該會更容易,但如果有人能告訴我確保表單中的電話號碼只有10個數字的正確方法,那也是很好的方法。謝謝。

+0

如果您的目標是在數據庫級別強制執行此操作,則表單不是正確的位置。在你的模型中使用驗證器。你也應該爲你的模型中的字段定義詳細名稱和'max_length'。然後,您不必重新定義模型在表單中的每個字段。您可以使用表單元類的fields屬性。 – trixn

回答

1

你不調用方法,因而isalpha:

if first_name.isalpha == False: 

您創建一個內置的方法對象因而isalpha,這是不假永遠。 我認爲這只是一個錯字,寫了這麼:

if first_name.isalpha(): 
    ... # your code 

對於電話號碼的使用方法clean_phone的驗證:

def clean_phone(self): 
    phone = self.cleaned_data['phone'] 
    if not phone.isdigit(): 
     raise forms.ValidationError('Phone number can only contains digits') 
    elif len(phone) != 10: 
     raise forms.ValidationError('Length of phone number must be 10 digits') 
    return phone 

編輯

這是絕對正確的,你沒有爲了描述forms.py文件中的字段,你應該在models.py中執行它,但是一些特殊的例如first_name只能包含你可以在forms.py中描述的字母。

首先,在所有數據庫約束(字段類型,最大長度,選擇,唯一值等)的models.py中創建一個Student模型。考慮到django自動創建id字段。

# models.py 

class Student(models.Model): 
    first_name = models.CharField(max_length=128) 
    last_name = models.CharField(max_length=128) 
    # Type of gender field depends on type of keys you used in GENDER_CHOICES 
    # CharField for chars, IntegerField for integers 
    gender = models.CharField(choices = GENDER_CHOICES, max_length=5) 
    ... 
    # Here you could validate your phone number length 
    # But you still have to check it for valide symbols (in forms.py) 
    phone = models.CharField(max_length = 10) 
    # and so on for all your fields 

之後,在forms.py中定義您的StudetForm。你不必用他們的約束來描述你所有的學生領域。

# forms.py 

from models import Student 

class StudentForm(forms.ModelForm): 
    class Meta: 
     model = Student 
     fields = '__all__' # Django adds all fields you've described in Student 
     # Then you could rename you fields labels, otherwise django will use names of model fields 
     labels = { 
      'first_name': 'First Name', 
      'last_name': 'Last Name', 
      ... 
     } 
     # And you also can override widgets for rendering. 
     # This feature could be useful for dates, because django default widget for DateField is TextInput. 
     widgets = { 
      'date': forms.SelectDateWidget, 
     } 

    # Now you could describe all validation methods 
    def clean_first_name(self): 
     first_name = self.cleaned_data['first_name'] 
     if not first_name.isalpha(): 
      return ValidationError('First name must contain only letters') 
     return first_name 
+0

它仍然沒有驗證。我閱讀了關於不把這個放在forms.py中的評論,但我不知道這是否是正確的解決方案,因爲在模型中放置'表單'會產生錯誤。 –

+0

您先定義模型。伊格爾斯的例子很棒。表單使用模型中定義的信息(數據類型,最大長度等)。「clean _」 - 「方法」只需包含對特定列的特殊檢查。 – mbieren