Djangoroidの奮闘記

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

Django e-commerce part68 Order Status

Order Statusを追加する

orders/models.py を追記する

ORDER_STATUS_CHOICES = (
    ('created', 'Created'),
    ('completed','Completed'),
)

class Order(models.Model):
    status = models.CharField(max_length=120, choices=ORDER_STATUS_CHOICES, default='created')
    cart = models.ForeignKey(Cart)
    user = models.ForeignKey(UserCheckout, null=True)
    billing_address = models.ForeignKey(UserAddress, related_name='billing_address', null=True, blank=True)
    shipping_address = models.ForeignKey(UserAddress, related_name='shipping_address', null=True, blank=True)
    shipping_total_price = models.DecimalField(max_digits=50, decimal_places=0, default=1000)
    order_total = models.DecimalField(max_digits=50, decimal_places=0)

    def __str__(self):
        return str(self.cart.id)

carts/views.py

class CheckoutFinalView(CartOrderMixin, View):
    def post(self, request, *args, **kwargs):
        order = self.get_order()
        if request.POST.get("payment_token") == "ABC":
            print (order.cart.items.all())
            order.mark_completed()
        return redirect("checkout")

postの時に、payment_tokenに特定の値が入っていた場合は、order.mark_completed() でcompletedにマークするファンクションをつける。

carts/views.py CheckoutFinalViewの修正

class CheckoutFinalView(CartOrderMixin, View):
    def post(self, request, *args, **kwargs):
        order = self.get_order()
        if request.POST.get("payment_token") == "ABC":
            order.mark_completed()
            del request.session.get["cart_id"]
            del request.session.get["order_id"]
        return redirect("checkout")

ポイント

  • completed_markがついたら、cart_id, order_idを削除する。(重複して発注しないように)
  • deleteされると、cart_id == Noneになる。

carts/views.py

このままだとエラーが発生する。

"Order.cart" does not allow null values.

ようは、Oder.cartに何か値が入っていないといけないということ。

そのため、get_order()は、cartがNoneの時は、作動しないようにする。

class CheckoutView(CartOrderMixin, FormMixin, DetailView):
...
    def get_context_data(self, *args, **kwargs):
          if self.get_cart() is not None:
              context["order"] = self.get_order()
...

ここでの問題点は、get_order()は、cartがある時は、ちゃんと作動するが、noneのときに、問題が発生してしまうという点。

mixins.pyを修正

class CartOrderMixin(object):

    def get_order(self, *args, **kwargs):
        cart = self.get_cart()
        if cart is None:
            return None

get_cart() がnoneの場合は、return Noneにしておく。そうすると、get_orderもnoneを返信するようになる。

これで, value=ABCの時に、注文を確定すると、Order のインスタンスのstatusが、completedに変わっているという注文確定のfunctionが仮作成される。