Djangoroidの奮闘記

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

Django e-commerce part48 Ajax part2

Cartの中で数量を変更したら、自動的に合計も計算される

view.html を編集

タグを、更新などと一緒のテーブルに入れる。

    <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>

jQueryを編集する

<script>
{% block jquery %}
$(".item-qty").change(function(){
    // $(this).next(".btn-update").fadeIn();
});
{% endblock %}

</script>

ひとまず、ajaxをコピペしてきて完成させてみる

.prev()は、戻り値 (ここでは、hidden タイプのinputタグを戻している) .val は、value あとは、その値をdataに辞書として格納

<script>
{% block jquery %}
$(".item-qty").change(function(){
    // $(this).next(".btn-update").fadeIn();
    // event.preventDefault();
    // prev()=戻り値
    var item = $(this).prev("input[type='hidden']").val();
    var qty = $(this).val() //item-qtyのvalueを代入
    var data = {
        item: item,
        qty: qty
    }
    console.log(data);
    $.ajax({
        type: "GET", //"POST"
        url: "{% url 'cart' %}",
        data: data,
        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted)
        },
        error: function(response, error){
            // console.log(response)
            // console.log(error)
            $("#add-form").submit()
        },
    })
});
{% endblock %}

</script>

carts/views.py を編集

from django.core.urlresolvers import reverse
...
    def get(self, request, *args, **kwargs):
        cart  = self.get_object()
        item_id = request.GET.get("item")
        delete_item = request.GET.get("delete", False)
        item_added = False

        if item_id:
        ...
            if request.is_ajax():
                return HttpResponseRedirect(reverse("cart"))

urlにitem_idの記載がある場合(つまり、item= の記述がある場合)に、さらにajax()があったら、'cart' にredirectする。

さらに、views.py を編集する。

    def get(self, request, *args, **kwargs):
    ....
        if request.is_ajax():
            try:
                total = cart_item.line_item_total
            except:
                total = None
            data = {
                "deleted": delete_item,
                "item_added": item_added,
                "line_total": total,
                }
            return JsonResponse(data)
  • cart_item.line_item_totalを試してみて、エラーだったら、total=Noneを入れておく。

views.html を編集する。

まず、<tr id='item-{{ item.item.id }}'> を追記して、trタグごとにidをつける。

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

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

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

さらに、<td id='item-line-total-{{ item.item.id }}'>{{ item.line_item_total }}</td> を追記して、item-line-total のidを、line_item_totalを表示するタグにつけておく。

{% 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 %}

jquery を修正

<script>
{% block jquery %}
$(".item-qty").change(function(){
    // $(this).next(".btn-update").fadeIn();
    // event.preventDefault();
    // prev()=戻り値
    var item = $(this).prev("input[type='hidden']").val();
    var qty = $(this).val() //item-qtyのvalueを代入
    var data = {
        item: item,
        qty: qty
    }
    console.log(data);
    $.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();
            } else {
                $("#item-line-total-"+item).text(data.line_total);
            }
        },
        error: function(response, error){
            // console.log(response)
            // console.log(error)
            $("#add-form").submit()
        },
    })
});
{% endblock %}

</script>

ここで大チョンボ発生!carts/views.py

        if item_id:
...
            if not request.is_ajax():
                return HttpResponseRedirect(reverse("cart"))
...

iajaxがない場合に、redirectするという条件分岐が、逆になっていた。 ajaxがある場合にredirectするってなってて、なぞのループが発生していた。。。