2017-12-14 16 views
1

私はDjangoアプリケーションにStripeの支払い処理を統合していますが、顧客のカードを確認するための正しい方法を見つけることができません情報を入力し、ユーザのStripe Customer IDを含むユーザテーブルに行を挿入します。Djangoのストライプ - フォームのフィールドではないフォームのclean()メソッドの戻り値を

理想的には、私の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() 

私は考えることができる唯一の他のソリューションは、ビューにstripe.Customer.create()関数を実行することです.py の後にフォームが検証されます。それはうまくいくでしょうが、フォームフィールドのすべての妥当性検査がforms.py内で行われるはずなので、コード化するのは正しい方法のようには思えません。

この状況で適切なDjangoコーディングの練習は何ですか?私は単に私のカード検証コードをviews.pyに移すべきでしょうか、あるいは、フォーム検証のためにforms.pyの中にカード検証コードを保存して、そこからcustomer.idを取り除くよりクリーンな方法がありますか?

答えて

1

適切な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 

その後form.is_valid()views.py、あなたは、このプロパティを呼び出すと思います。

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!") 

...と、まだviews.pyform.customer

私はどちらもうまくいくはずだと思いますが、コードはテストしていません。

+0

それを得ました - 完全な意味で、Borut!応答のおかげで、私はこれを正解として受け入れました。クイックフォローアップ:clean()メソッドにすべてのフォーム解析ロジックを含めるには、適切なdjangoコーディング慣行と考えてください。たとえば、「users =」コードブロックをviews.pyからforms.pyのclean()メソッドに移動する必要がありますか? – Sam

+0

フォームの検証に関連するすべてを 'clean()'の中に含めることは良い習慣です。フォーム(またはユーザーが投稿したデータ)をビューで検証するべきではありません。 'clean()'の 'user'バリデーションについて私は私のプロジェクトのいくつかをチェックして、私がそれをしたか、または私に意味がある多くのケースを見つけていません。 – Borut

+0

素敵です。ご協力ありがとうございました! – Sam

関連する問題