Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django e-commerce part73 Braintree Instance Methods

Braintree Instance Methods

orders/models.py get_braintree_id メソッドを設定する。

class UserCheckout(models.Model):
...
    @property
    def get_braintree_id(self,):
        self = instance
        if not instance.braintree_id:
            result = braintree.Customer.create({
                "email": instance.email,
            })
            if result.is_success:
                instance.braintree_id = result.customer.id
                instance.save()

def update_braintree_id(sender, instance, *args, **kwargs):
    if not instance.braintree_id:
        instance.get_braintree_id

post_save.connect(update_braintree_id, sender=UserCheckout)

ポイント

  • braintreeのid取得を関数に設定している。
  • @property のデコレーターで、メソッドをpropetyに変更している。そのため、instance.get_braintree_id で値を取得できる。(プロパティのため、最後の()が不要)プロパティについては、こちらの記事がわかりやすかったです!ありがとうございます!
  • なぜプロパティにするかというのはよくわからない。instance.braintree_id = instance.get_braintree_id()とかかなけばいけないところを、instance.get_braintree_id で済むので、シンプルにできるからかなぁ。

orders/models.py get_client_token を追記する。

公式ドキュメントはこちら

ClientToken.generate() | Python - Braintree Developer Documentation

    def get_client_token(self):
        customer_id = self.get_braintree_id
        if customer_id:
            client_token = braintree.ClientToken.generate({
                "customer_id": customer_id
            })
            return client_token
        return None
  • 戻り値の、client_token は、ClientTokenのインスタンス(なはず。)。これは、customer_id=braintree_idのclient_tokenになっている。

carts/views.py の、CheckoutViewで、contextとして、client_tokenを渡す。

class CheckoutView(CartOrderMixin, FormMixin, DetailView):
...
        if self.request.user.is_authenticated():
            context["client_token"] = user_checkout.get_client_token()
...
        if user_check_id != None:
...
            if not self.request.user.is_authenticated():#GUEST USER
                user_checkout_2 = UserCheckout.objects.get(id=user_check_id)
                context["client_token"] = user_checkout_2.get_client_token()
...
  • ユーザーが認証済みの場合は、emailで絞り込まれたUserCheckoutinstanceである、user_checkoutのclient_tokenをcontextとして渡す。

  • すでにuser_check_idが作られている場合で、ユーザーがゲストユーザーの場合は、user_check_idを元に、UserCheckoutを絞り込んで、user_checkout_2にインスタンスを渡し、それを元に、client_tokenをcontextに渡す。

checkout_view.html で表示してみる。

{{ client_token }}

やってみると、Noneが表示される。これは、get_client_tokenがnoneを返しているので、その辺りに問題がある。たぶん、get_braintree_idが、returnが設定されていないためと思われる。

    @property
    def get_braintree_id(self,):
        instance = self
        if not instance.braintree_id:
            result = braintree.Customer.create({
                "email": instance.email,
            })
            if result.is_success:
                instance.braintree_id = result.customer.id
                instance.save()
        return instance.braintree_id

これでおそらくちゃんと表示される。

{{ client_token }} は、blcokcontentの外に設定しておく。