我正在创建一个用户在注册和登录后填写的“保密协议”表单。我正在使用AllAuth的自定义注册表单并预先填充表单的部分内容。我将第一个和最后一个名字预填充到表单的顶部,如下面的第一个屏幕截图所示,但作为我正在设置的数字签名的一部分;我需要验证键入的签名字段是否匹配第二个屏幕截图中连接在一起的first_name
和last_name
的名称。我知道我需要设置一个基于Django Form & Field Validations的验证器,我已经尝试了几件事,但是我无法理解它。将这些放在一起的任何帮助都将是巨大的......谢谢。
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile", verbose_name="user")
...
class NonDisclosure(Timestamp):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="nda", verbose_name="profile")
user_signature = models.CharField(max_length=250, verbose_name='Signature')
user_street = models.CharField(max_length=250, verbose_name='Street Address')
user_city = models.CharField(max_length=250, verbose_name='City')
user_state = models.CharField(max_length=2, verbose_name='State Initials')
user_zip = models.IntegerField(verbose_name='Zip Code')
phone = models.CharField(max_length=25, verbose_name='Phone Number')
cash_on_hand = models.CharField(max_length=250, verbose_name='Cash on Hand')
value_of_securities = models.CharField(max_length=250, verbose_name='Value of Securities')
equity_in_real_estate = models.CharField(max_length=250, verbose_name='Equity on Real Estate')
other = models.CharField(max_length=250, verbose_name='Other Assets')
@property
def username(self):
return self.profile.username
@property
def first_name(self):
return self.profile.first_name
@property
def last_name(self):
return self.profile.last_name
@property
def email(self):
return self.profile.email
class Meta:
verbose_name = 'Non Disclosure Agreement'
verbose_name_plural = 'Non Disclosure Agreements'
def __str__(self):
return "%s" % self.profile
def get_absolute_url(self):
return reverse('nda_detail', args=[str(self.id)])
我的观点:
class NonDisclosureForm(BaseModelForm):
cash_on_hand = forms.CharField(required=False)
value_of_securities = forms.CharField(required=False)
equity_in_real_estate = forms.CharField(required=False)
other = forms.CharField(required=False)
class Meta:
model = NonDisclosure
fields = ['user_signature', 'user_street', 'user_city', 'user_state', 'user_zip', 'phone', 'cash_on_hand', 'value_of_securities', 'equity_in_real_estate', 'other']
class NdaCreate(CreateView):
form_class = NonDisclosureForm
template_name = 'nda/nda_form.html'
def form_valid(self, form):
form.instance.profile = Profile.objects.get(user=self.request.user)
form.instance.created_by = self.request.user
return super(NdaCreate, self).form_valid(form)
答案 0 :(得分:1)
首先,您应该将ModelForm
作为子类,而不是BaseModelForm
。为user_signature
字段写一个clean_<fieldname>
方法,并确保该值符合预期。您可以访问self.instance.created_by
进行检查。
class NonDisclosureForm(ModelForm):
...
class Meta:
model = NonDisclosure
fields = ['user_signature', ...]
def clean_user_signature(self):
user_signature = self.cleaned_data['user_signature']
expected_name = '%s %s' % (self.instance.created_by.first_name, self.instance.created_by.last_name)
if user_signature != expected_name:
raise forms.ValidationError('Signature does not match')
return user_signature
然后,您需要更新视图,以便设置instance.created_by
。您可以通过覆盖get_form_kwargs
来完成此操作。
class NdaCreate(CreateView):
def get_form_kwargs(self):
kwargs = super(NdaCreate, self).get_form_kwargs()
kwargs['instance'] = NonDisclosure(created_by=self.request.user)
return kwargs