Djangoroidの奮闘記

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

Django e-commerce part60 Order Model

OrderのModelを整えていく

orders/views.pyを少し修正する

class AddressSelectFormView(FormView):
...
    def form_valid(self, form, *args, **kwargs):
        print (form.cleaned_data["billing_address"])
        print (form.cleaned_data["shipping_address"])
        return super(AddressSelectFormView, self).form_valid(form, *args, **kwargs)

validに、formの引数を渡すように設定する。form_validの後は、get_success_urlにリダイレクトする。

Editing mixins | Django documentation | Django

order/models.py 2、Order クラスを作成

class Order(models.Model):
    cart = models.ForeignKey(Cart)
    user = models.ForeignKey(UserCheckout)
    billing_address = models.ForeignKey(UserAddress, related_name='billing_address')
    shipping_address = models.ForeignKey(UserAddress, related_name='shipping_address')
    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)

related_name:

モデルフィールドリファレンス — Django 1.4 documentation

リレーション先のオブジェクトから逆参照するときに使われる名前です。

carts/views.py のCheckoutViewを修正する。

class CheckoutView(FormMixin, DetailView):
...
    def get(self, request, *args, **kwargs):
        get_data = super(CheckoutView, self).get(request, *args, **kwargs)

        cart = self.get_object()
        user = user_checkout
        billing_address = ?
        shipping_address = ?

        new_order = Order()
        new_order.cart = cart
        new_order.user = user
        new_order.billing_address = billing_address
        new_order.shipping_address = shipping_address
        new_order.save()

        return get_data

ポイント

  • getを上書きするfunction、getは、returnとして、get_data を返す。
  • getは、引数として、requestをとる。
  • ここでは、CheckoutViewのgetメソッドが実行された時に、その内容が、Order()にsaveされるように設定しようとしている。
  • なぜ、cartviewで設定するかというと、cartのidが、orderの肝になるから。

さらにcarts/views.py を修正する。

  • user_checkout_id をrequestからゲットする。
  • user_checkout_idがある場合は、user_checkoutに、idで絞り込んだ、UserCheckoutのインスタンスをゲットする。
class CheckoutView(FormMixin, DetailView):
...

    def get(self, request, *args, **kwargs):
        get_data = super(CheckoutView, self).get(request, *args, **kwargs)

        cart = self.get_object()

        user_checkout_id = request.session.get("user_checkout_id")

        if user_checkout_id != None:
            user_checkout = UserCheckout.objects.get(id=user_checkout_id)
...

orders/views.py

class AddressSelectFormView(FormView):
...
    def form_valid(self, form, *args, **kwargs):
        billing_address = form.cleaned_data["billing_address"]
        shipping_address = form.cleaned_data["shipping_address"]
        self.request.session["billing_address"] = billing_address.id
        self.request.session["shipping_address"] = shipping_address.id
        return super(AddressSelectFormView, self).form_valid(form, *args, **kwargs)
  • AddressSelectのform_validが発動するときに、billing_addressのidと、shipping_addressのidをsessionに格納する。

carts/views.pyのcheckoutView をさらに修正する。

class CheckoutView(FormMixin, DetailView):
...
    def get(self, request, *args, **kwargs):
        get_data = super(CheckoutView, self).get(request, *args, **kwargs)
        cart = self.get_object()
        user_checkout_id = request.session.get("user_checkout_id")
        if user_checkout_id != None:
            user_checkout = UserCheckout.objects.get(id=user_checkout_id)
            billing_address_id = request.session.get("billing_address_id")
            shipping_address_id = request.session.get("shipping_address_id")

            if billing_address_id == None or shipping_address_id == None:
                return redirect("order_address")
            else:
                billing_address = UserAddress.objects.get(id=billing_address_id)
                shipping_address = UserAddress.objects.get(id=shipping_address_id)
            try:
                new_order_id = request.session["order_id"]
                new_order = Order.objects.get(id=new_order_id)
            except:
                new_order = Order()
                request.session["order_id"] = new_order.id

            new_order.cart = cart
            new_order.user = user_checkout
            new_order.billing_address = billing_address
            new_order.shipping_address = shipping_address
            new_order.save()

ポイント

  • new_order_id が作られているかどうかを、request.session["order_id"]で確認して、errorが出たら、新しくsessionidを作成する。

現時点では、NOT NULL constraint failed: orders_order.order_totalとか、cart自体が作れていない場合にerrogが出てしまうので、それを次回解消する。

疑問点

  • sessionの有効期限は??