我尝试进行表单验证,以便某些字段只接受某些类型的输入,例如名称只接受字母和电话号码只接受10个数字。我尝试对第一个名称进行验证,如下所示:
#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 :(得分:1)
你没有调用方法isalpha:
if first_name.isalpha == False:
您创建了一个内置方法对象isalpha,它不是False。 我认为这只是一个错字,所以写道:
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