読者です 読者をやめる 読者になる 読者になる

Djangoroidの奮闘記

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

Django e-commerce part51 Empty Cart

カートが空の時の動作を設定する

現時点では、post_saveしか使っていなため、post_deleteを使ってみる。

post_delete

...
from django.db.models.signals import pre_save, post_save, post_delete
...
def cart_item_post_save_receiver(sender, instance, *args, **kwargs):
    instance.cart.update_subtotal()

post_save.connect(cart_item_post_save_receiver, sender=CartItem)

post_delete.connect(cart_item_post_save_receiver, sender=CartItem)
...

機能自体は、cart_item_post_save_receiverと同じのため、delete signalがあった時に、cart_item_post_save_receiverに繋げばOK。

ただ、これだと、数量を0にして、削除した場合には、一度更新をしないといけない。(ajaxにはsubtotalの空の場合の挙動が伝わっていない。)

view.html を修正する。

...
    $.ajax({
        type: "GET", //"POST"
        url: "{% url 'cart' %}",
        data: data,
        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted);
            if (data.deleted){
                $("#item-"+item).fadeOut();
<span style="color: #ff0000">                $("#subtotal").text("Subtotal: " + data.subtotal);
</span>            } else {
                $("#item-line-total-"+item).text(data.line_total);
                $("#subtotal").text(data.subtotal);
            }
...

view.html のblock contentの箇所を修正する。

空の時はリストを表示させない。

{% if object.cartitem_set.count < 1 %}

<div class='col-sm-6 col-sm-offset-3 text-center'>
<h1>あなたのカートは空です</h1>
<p>買い物を続ける</p>
</div>
{% else %}
<table class='table'>

{% for item in object.cartitem_set.all %}

<tr id='item-{{ item.item.id }}'>

    <td>{{ item.item.get_title }}</td>

    <td>
    <form action="." method="GET">
    <input type='hidden' name='item' value='{{ item.item.id }}'/>
    <input type='number' class='item-qty' name='qty' value='{{ item.quantity }}'/>
    <input type='submit' class='btn-update btn btn-link' value='更新する' style='display:none;'/>
    </form>
    </td>
    <td id='item-line-total-{{ item.item.id }}'>{{ item.line_item_total }}</td>
    <td class='text-right'><a href='{{ item.remove }}'>削除</a></td>
</tr>
{% endfor %}

<tr>

<td id='subtotal' colspan='4' class='text-right'>小計: {{ object.subtotal }}</td>

</tr>

</table>
{% endif %}

carts/views.py にコードを追記する

    def get(self, request, *args, **kwargs):
...
        if request.is_ajax():
...

            try:
                total_items = cart_item.cart.items.count()
            except:
                total_items = 0

            data = {
                "deleted": delete_item,
                "item_added": item_added,
                "line_total": total,
                "subtotal": subtotal,
                "flash_message": flash_message,
                "total_items": total_items,
                }
            return JsonResponse(data)

cartにあるitemの数量をdataに渡す。

view.html で空になった場合の動作を設定する。

...

<span style="color: #ff0000">            if (data.total_items == 0) {
                $(".table").fadeOut()
                $(".main-content").text("あなたのカートは空です")
            }</span>
...

<span style="color: #ff0000"><div class='row main-content'>
</span>{% if object.cartitem_set.count < 1 %}

<div class='col-sm-6 col-sm-offset-3 text-center'>
<h1>あなたのカートは空です</h1>
<p>買い物を続ける</p>
<span style="color: #ff0000"></div>
</span>{% else %}
<table class='table'>
...
</div>

{% endblock %}

empty_cart.html を新規作成する。

<div class='col-sm-6 col-sm-offset-3 text-center'>
<h1>あなたのカートは空です</h1>
<p>買い物を続ける</p>
</div>

view.htmlにincludeする

<div class='row main-content'>
{% if object.cartitem_set.count < 1 %}

{% include "carts/empty_cart.html" %}

{% else %}

さらに view.htmlの.ajax部分も修正する。

...
            if (data.total_items == 0) {
                $(".table").fadeOut()
                var template = "{% include 'carts/empty_cart.html' %}";
                $(".main-content").html(template);
            }
...

empty_cart.htmlを修正する。(jQueryで、読み込む場合は、改行などを削除する)

<div class='col-sm-6 col-sm-offset-3 text-center'><h1>あなたのカートは空です</h1><p>買い物を続ける</p></div>