我正在将Stripe支付处理集成到我的Django应用程序中,我无法找出验证客户卡信息的“正确”方法,并在包含用户条带客户ID的Users表中插入一行。
理想情况下,我喜欢按照以下方式执行某些操作,其中我的CheckoutForm会验证卡详细信息并在不正确的情况下引发表单ValidationError。但是,使用这个解决方案,我无法找到一种方法来获取clean()函数生成的customer.id。
forms.py
class CheckoutForm(forms.Form):
email = forms.EmailField(label='E-mail address', max_length=128, widget=forms.EmailInput(attrs={'class': 'form-control'}))
stripe_token = forms.CharField(label='Stripe token', widget=forms.HiddenInput)
def clean(self):
cleaned_data = super().clean()
stripe_token = cleaned_data.get('stripe_token')
email = cleaned_data.get('email')
try:
customer = stripe.Customer.create(
email=email,
source=stripe_token,
)
// I can now get a customer.id from this 'customer' variable, which I want to insert into my database
except:
raise forms.ValidationError("It looks like your card details are incorrect!")
views.py
# If the form is valid...
if form.is_valid():
# Create a new user
user = get_user_model().objects.create_user(email=form.cleaned_data['email'], stripe_customer_id=<<<I want the customer.id generated in my form's clean() method to go here>>>)
user.save()
我能想到的唯一其他解决方案是在表单验证后运行views.py 中的stripe.Customer.create()函数。这样做有用,但它似乎不是编码事物的“正确”方式,因为据我所知,表单字段的所有验证都应该在forms.py中完成。
在这种情况下,正确的Django编码实践是什么?我应该将我的卡验证代码移动到views.py,还是有更简洁的方法将卡验证代码保存在forms.py中并从中获取customer.id?
答案 0 :(得分:2)
在这种情况下,我不认为正确的Django编码实践与Python编码实践有任何不同。由于Django表单只是一个类,因此您可以为customer
定义属性。像这样:
class CheckoutForm(forms.Form):
email = forms.EmailField(label='E-mail address', max_length=128, widget=forms.EmailInput(attrs={'class': 'form-control'}))
stripe_token = forms.CharField(label='Stripe token', widget=forms.HiddenInput)
_customer = None
def clean(self):
cleaned_data = super().clean()
stripe_token = cleaned_data.get('stripe_token')
email = cleaned_data.get('email')
try:
self.customer = stripe.Customer.create(
email=email,
source=stripe_token,
)
except:
raise forms.ValidationError("It looks like your card details are incorrect!")
@property
def customer(self):
return self._customer
@customer.setter
def customer(self, value):
self._customer = value
然后在views.py
之后form.is_valid()
,您将此属性称为。
if form.is_valid():
customer = form.customer
或者@property
可能是一种矫枉过正,你可以这样做:
class CheckoutForm(forms.Form):
email = forms.EmailField(label='E-mail address', max_length=128, widget=forms.EmailInput(attrs={'class': 'form-control'}))
stripe_token = forms.CharField(label='Stripe token', widget=forms.HiddenInput)
customer = None
def clean(self):
cleaned_data = super().clean()
stripe_token = cleaned_data.get('stripe_token')
email = cleaned_data.get('email')
try:
self.customer = stripe.Customer.create(
email=email,
source=stripe_token,
)
except:
raise forms.ValidationError("It looks like your card details are incorrect!")
... form.customer
中仍然是views.py
。
我想两者都应该有效,但我还没有测试过代码。