为什么我的regex_validator在formset中没有覆盖干净方法?

时间:2017-08-03 14:36:32

标签: python django forms

我的目标

以下代码应显示 formset ,其中包含一定数量的 TravellerForm ,然后验证它们并保存 CompleteSubscription 和他的旅行者相关。

只有主要联系人 - 第一个表格 - 应该有一个由正则表达式验证的E.164格式的电话号码。

以下代码的结果

它正确地取消了第一个以外的其他表单的电话号码字段,并且正确显示了我需要的字段

然后,当我提交表单时,旅行者会保存在我的数据库中,包括第一个,但我在其中放入了无效的电话号码。订阅已正确保存。

为了解决这个问题,我已经覆盖了clean_phone_number方法,它看起来很有效,但它给了我两个错误而不仅仅是一个错误。

  • 电话号码必须为E.164格式。例如:+33123456789
  • 确保此值最多包含16个字符(目前为143个)。

我的问题

为什么我需要覆盖clean_phone_number方法来显示错误,是不是应该在保存之前调用其表单的clean方法的formset?

如果是这样,为什么我覆盖它时调用了clean_phone_number方法?

我很有意思地知道当我实际输入12个字符时django如何计算143个字符(我想删除一个字段可能会破坏一些计数)。

代码本身

有模板,

<form method="post">
    {% csrf_token %}
    {{ formset.management_form }}
    {% for form in formset %}
    {{  form.as_p }}
    </br>
    {% endfor %}
    <input type="submit" value="Valider" />
</form>

观点,

def set_main_form(formset):
    is_main = True
    for form in formset:
        if is_main:
            is_main = False
        else:
            del form.fields['phone_number']

# Main contact is the first Travelller
def complete_subscription_create(request, base_pk):
    base = BaseSubscription.objects.get(pk=base_pk)
    number_forms = base.nb_adults + base.nb_children + base.nb_babies

    TravellerFormSet = modelformset_factory(Traveller, form=TravellerForm,
                                            extra=number_forms)

    if request.method == 'POST':
        formset = TravellerFormSet(request.POST, request.FILES)
        set_main_form(formset)
        if formset.is_valid():
            base = BaseSubscription.objects.get(pk=base_pk)
            subscription = CompleteSubscription(base_subscription=base)
            subscription.save()
            formset[0].instance.is_main_contact = True
            for form in formset:
                form.instance.subscription = subscription
            formset.save()
            return redirect('home')
    else:
        formset = TravellerFormSet()
        set_main_form(formset)
    return render(request, 'offerspace/completesubscription_form.html',
                  {'formset': formset})

表单中实例化的表单

class TravellerForm(forms.ModelForm):
    class Meta:
        model = Traveller
        fields = ('first_name', 'second_name', 'last_name',
                  'passport_country', 'phone_number')

    # For some reasons, the regex validator works when I uncomment this
    #def clean_phone_number(self):
        #cleaned_data = super(TravellerForm, self).clean()
        #return cleaned_data

TravellerForm的模型

class Traveller(models.Model):
    first_name = models.CharField(max_length=128)
    second_name = models.CharField(max_length=128, blank=True)
    last_name = models.CharField(max_length=128)

    # This field is in E.164 Format, see https://en.wikipedia.org/wiki/E.164
    # for  more informations about this format
    phone_error_message = """
        Phone number must be in E.164 format.
        Ex: +33123456789
        """
    phone_regex = RegexValidator(regex=r'^\+?1?\d{8,15}$',
                                 message=phone_error_message,
                                 code='invalid_phone_number')
    phone_number = models.CharField(validators=[phone_regex], blank=True,
                                    max_length=16)
    passport_country = models.ForeignKey(Country)
    is_main_contact = models.BooleanField(default=False)
    subscription = models.ForeignKey(CompleteSubscription)

在视图中实现了CompleteSubscription模型,

class CompleteSubscription(models.Model):
    base_subscription = models.OneToOneField(BaseSubscription)
    final_price = models.PositiveIntegerField(default=0)

0 个答案:

没有答案