djangoプロジェクト開発のcartページ


cartページ
1.カートページ追加商品
私たちがappで商品を購入するのは、まず商品ページで商品を選んでカートに追加し、カートから決済して、この機能をどのように実現するかを考えています.
1.1表の関連付け
商品、カート、ユーザー間は、表の関連に変換することができ、カートは関係表の役割に相当し、ユーザーと商品の間には多対多の関係となる.まずmodelsに行きます.pyカートの模型を書く
class Cart(models.Model):
    c_user=models.ForeignKey(User)
    c_goods=models.ForeignKey(Goods)

    c_goods_num=models.IntegerField(default=1)
    c_is_select=models.BooleanField(default=True)
    class Meta:
        db_table = 'sxw_cart'

新しいバージョンのdjangoでは、外部キーにon_を追加する必要があります.delete=models.CASCADEプロパティです.そうしないと、エラーが発生します.外部キーはユーザと商品に関連付けられ,カスケード削除を採用し,カートから削除されるとユーザも関連情報を削除する.データ移行を実行します.
1.2商品IDを取得し、数量num
カートをクリックすると、クリックイベントが追加され、このイベントはajaxリクエストを開始し、jsを通じてgoodsidをバックグラウンドに伝え、
market.js
 $(".addShopping").click(function(){
     
        console.log('add');
        var $add=$(this);
        var goodsid=$add.attr('goodsid');
        $.get('/sxw/addtocart/',{
     'goodsid':goodsid},function(data){
     
            console.log(data);
            if (data['status'] === 302){
     
                window.open('/sxw/login/',target="_self");
            }else if(data['status']===200){
     
                $add.prev('span').html(data['c_goods_num']);
            }
        })
    })

1.3商品idとnumをバックグラウンドに転送する
上記の手順で商品のidとnumを取り、ajaxを使用してバックグラウンドに転送します.まず/sxw/addtocart/function(data)にデータを転送するのは、ajaxリクエストが開始された後、バックグラウンドでリクエストを受信すると、この関数をアクティブに呼び出し、データをdataに格納する役割を果たすコールバック関数です.ビュー関数を書きます.ajaxリクエストなので、jsonに戻ったほうがいいです.
def add_to_cart(request):
    goodsid=request.GET.get('goodsid')
    #     id,       id,        
    carts=Cart.objects.filter(c_user=request.user).filter(c_goods_id=goodsid)
    #          ,      1;    ,    id     
    if carts.exists():
        cart_obj=carts.first()
        cart_obj.c_goods_num = cart_obj.c_goods_num + 1
    else:
        cart_obj=Cart()
        cart_obj.c_goods_id=goodsid
        cart_obj.c_user=request.user
    cart_obj.save()
    data={
     
        'status':200,
        'msg':'add success',
        'c_goods_num':cart_obj.c_goods_num
    }
    #           
    return JsonResponse(data=data)

最後にurlを追加
 url(r'^addtocart/',views.add_to_cart,name='add_to_cart'),

1.4カートから商品を取り除く
カートから商品を除去する方法は追加と同じです.market.js
$(".subShopping").click(function(){
     
    console.log('sub');
    var $sub=$(this);
    var goodsid=$sub.attr('goodsid');
    $.get('/sxw/subtocart/',{
     'goodsid':goodsid},function(data){
     
        console.log(data);
        if (data['status'] === 302){
     
            window.open('/sxw/login/',target="_self");
        }else if(data['status']===200){
     
            $sub.prev('span').html(data['c_goods_num']);
        }
    })
})

ビュー関数
def sub_to_cart(request):
    goodsid = request.GET.get('goodsid')
    carts = Cart.objects.filter(c_user=request.user).filter(c_goods_id=goodsid)
    data = {
     
        'status': 200,
        'msg': 'add success',
    }
    if carts.exists():
        cart_obj = carts.first()
        if cart_obj.c_goods_num > 1:
            cart_obj.c_goods_num = cart_obj.c_goods_num - 1
            cart_obj.save()
            data['c_goods_num'] = cart_obj.c_goods_num
        else:
            cart_obj.delete()
            data['c_goods_num'] = 0

    return JsonResponse(data=data)

ルーティングの設定
 url(r'^subtocart/',views.sub_to_cart,name='sub_to_cart'),

2カートページ
2.1 cartビュー関数およびページ
def cart(request):
    carts=Cart.objects.filter(c_user=request.user)
    is_all_select= not carts.filter(c_is_select=False).exists()

    data={
     
        'title':'   ',
        'carts':carts,
        'is_all_select':is_all_select,
        'total_price':get_total_price()
    }
    return render(request,'cart.html',context=data)

cart.html
{
     % extends 'base_main.html' %}
{
     % load static %}

{
     % block ext_css %}
    {
     {
      block.super }}
    <link rel="stylesheet" href="{% static 'main/css/cart.css' %}">
{
     % endblock %}

{
     % block ext_js %}
    {
     {
      block.super }}
    <script type="text/javascript" src="{% static 'main/js/cart.js'%}"></script>

{
     % endblock%}

{
     % block content %}
<div id="cart">
    <h3>   </h3>
    <div class="full">
        <section>
            <ul>
                <li>   :aimo</li>
                <li>110</li>
                <li></li>
            </ul>
            <section class="bill">
                <p>    </p>
                <p>¥0  ,22:00  ¥30   </p>
                <a href="#">    </a>
            </section>


            <section class="delivery">
                <span>    </span>
                <span>     </span>
                <a href="#">   ></a>
            </section>
            <section class="delivery">
                <span>    </span> <input type="text" placeholder="   100         "/>
            </section>
            <ul>
                {
     % for cart in carts %}
                    <li class="menulist" cartid="{
     { cart.id }}">
                        <div class="confirm">
                            <span>
                                {
     % if cart.c_is_select %}
                                <span></span>
                                {
     % else %}
                                <span></span>
                                {
     % endif %}
                            </span>
                        </div>
                        <a href="#">
                            <img src="{
     { cart.c_goods.productimg }}" alt="{
     {cart.c_goods.productlongname}}">
                        <p>{
     {
     cart.c_goods.productlongname }}</p>
                            <p class="presentPrice">{
     {
     cart.c_goods.price}}</p>
                        </a>
                        <section>
                            <button class="subShopping">-</button>
                            <span>{
     {
     cart.c_goods_num}}</span>
                            <button class="addShopping">+</button>
                        </section>

                    </li>
                {
     % endfor%}
            </ul>
            <li class="payTheBill">
                <div class="all_select">
                    <span>
                        {
     % if is_all_select %}
                        <span></span>
                        {
     % else %}
                        <span></span>
                        {
     % endif %}
                    </span>
                </div>
                <p>
                    <span>  </span>
                    <span>  :</span>
                    <span id="total_price">{
     {
     total_price}}</span>
                </p>
                <span id="make_order">  </span>
            </li>
        </section>
    </div>
</div>

{
     % endblock %}

2.2カートの状態変更
カート全選
ショッピングカートのデフォルト状態の全選択ボタンが選択され、内部のすべての商品が選択されます.全選ボタンが選択されていない場合、内部商品に選択されていないものがあれば、全選は選択されていないはずです.全選択をクリックすると、元の状態が選択され、全選択とすべての商品が選択されていません.元の状態は未選択で、全選とすべての商品が選択になって単一の商品をクリックして、商品は選択から未選択になって、全選は必ず未選択になります;商品が選択されていないものから選択されている場合、すべての選択のデフォルト状態は選択されていないか、選択されている可能性があります.
カートはまた、選択した商品の数と価格に基づいて、自動的に注文総額を計算するはずです.
views_helpsに商品の総価格を計算する関数を書きます
def get_total_price():
    carts=Cart.objects.filter(c_is_select=True)
    total=0
    for cart in carts:
        total += cart.c_goods_num * cart.c_goods.price
    total=float('%.2f'%total)
    return total

cart.js
$(function (){
     
    $(".confirm").click(function(){
     
        console.log("change state");
        var $confirm=$(this);
        var $li=$confirm.parents("li");
        var cartid=$li.attr('cartid');
        $.getJSON("/sxw/changecartstate/",{
     'cartid':cartid},function (data){
     
            console.log(data);
            if (data['status']===200){
     
                $("#total_price").html(data['total_price']);
                if(data['c_is_select']){
     
                    $confirm.find("span").find("span").html("√");
                }else{
     
                    $confirm.find("span").find("span").html("");
                }
                if (data['is_all_select']){
     
                    $(".all_select span span").html("√");
                }else{
     
                    $(".all_select span span").html("");
                }
            }
        })
    })
    $(".subShopping").click(function(){
     
        var $sub=$(this);
        var $li =$sub.parents("li");
        var cartid=$li.attr("cartid");
        $.getJSON("/sxw/subshopping/",{
     "cartid":cartid},function(data){
     
            console.log(data);
            if (data['status']===200){
     
                 $("#total_price").html(data['total_price']);
                if (data['c_goods_num']>0){
     
                    var $span =$sub.next("span");
                    $span.html(data['c_goods_num']);
                }else{
     
                    $li.remove();
                }
            }
        })
    })
    $(".all_select").click(function(){
     
        var $all_select=$(this);
        var select_list=[];
        var unselect_list=[];
        $(".confirm").each(function(){
     
            var $confirm=$(this);
            var cartid =$confirm.parents("li").attr("cartid");
            if($confirm.find("span").find("span").html().trim()){
     
                select_list.push(cartid);
            }else{
     
                unselect_list.push(cartid);
            }
        })
        console.log(select_list);
        console.log(unselect_list);
        if(unselect_list.length > 0 ){
     
            $.getJSON('/sxw/allselect/',{
     'cart_list':unselect_list.join('#')},function(data){
     
                console.log(data);
                if(data['status']===200){
     
                    $(".confirm").find("span").find("span").html("√");
                    $all_select.find("span").find("span").html("√");
                    $("#total_price").html(data['total_price']);
                }
            })
        }else{
     
            if (select_list.length > 0){
     
                $.getJSON('/sxw/allselect/',{
     'cart_list':select_list.join('#')},function(data){
     
                console.log(data);
                if(data['status']===200){
     
                    $(".confirm").find("span").find("span").html("");
                    $all_select.find("span").find("span").html("");
                    $("#total_price").html(data['total_price']);
                }
            })
            }
        }
    })

views.py
def change_cart_state(request):
    cart_id=request.GET.get('cartid')
    cart_obj=Cart.objects.get(pk=cart_id)
    cart_obj.c_is_select=not cart_obj.c_is_select
    cart_obj.save()
    is_all_select=not Cart.objects.filter(c_user=request.user).filter(c_is_select=False).exists()
    data={
     
        'status':200,
        'msg':'change ok',
        'c_is_select':cart_obj.c_is_select,
        'is_all_select':is_all_select,
        'total_price': get_total_price(),
    }
    return JsonResponse(data=data)


def sub_shopping(request):
    cart_id = request.GET.get('cartid')
    cart_obj = Cart.objects.get(pk=cart_id)
    data = {
     
        'status':200,
        'msg':'ok',
    }
    if cart_obj.c_goods_num > 1:
        cart_obj.c_goods_num = cart_obj.c_goods_num - 1
        cart_obj.save()
        data['c_goods_num']=cart_obj.c_goods_num
    else:
        cart_obj.delete()
        data['c_goods_num']=0
    data['total_price'] = get_total_price()
    return JsonResponse(data=data)


def all_select(request):
    cart_list=request.GET.get('cart_list')
    cart_list=cart_list.split('#')
    carts=Cart.objects.filter(id__in=cart_list)
    for cart_obj in carts:
        cart_obj.c_is_select = not cart_obj.c_is_select
        cart_obj.save()

    print(cart_list)
    data={
     
        'status':200,
        'msg':'ok',
        'total_price':get_total_price(),
    }
    return JsonResponse(data=data)

ルーティングの設定
url(r'^changecartstate/',views.change_cart_state,name='change_cart_state'),
url(r'^subshopping/',views.sub_shopping,name='sub_shopping'),
url(r'^allselect/',views.all_select,name='all_select'),

3登録検出ミドルウェア
ユーザーログインを必要としないページもあれば、ユーザーログインを必要とするページもあります.毎回ユーザーがログインしているかどうかを判断すると、コード量が大きいだけでなく、結合性も低いです.インプリメンテーション機能のたびに、ユーザーがログインしているかどうかを判断するために、ミドルウェアを使用して、どのページにログインする必要があるかを選択できます.もちろん、アクセサリーも使えます.
ここではlogincheckmiddlewareを作成します.py
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin

from App.models import User
REQUIRE_LOGIN=[
    '/sxw/cart/',
    '/sxw/orderdetail/',
    '/sxw/orderlistnotpay/',
]
REQUIRE_LOGIN_JSON=[
    '/sxw/addtocart/',
    '/sxw/changecartstate/',
    '/sxw/makeorder/',
]
class LoginMiddleware(MiddlewareMixin):
    def process_request(self,request):
        if request.path in REQUIRE_LOGIN_JSON:
            user_id=request.session.get('user_id')
            if user_id:
                try:
                    user=User.objects.get(pk=user_id)
                    request.user=user
                except:
                    data={
     
                        'status':301,
                        'msg':'user not avaliable'
                    }
                    return JsonResponse(data=data)
                    #return redirect(reverse('sxw:login'))
            else:
                data = {
     
                    'status': 301,
                    'msg': 'user not login'
                }
                return JsonResponse(data=data)
                #return redirect(reverse('sxw:login'))
        if request.path in REQUIRE_LOGIN:
            user_id = request.session.get('user_id')
            if user_id:
                try:
                    user = User.objects.get(pk=user_id)
                    request.user = user
                except:
                    return redirect(reverse('sxw:login'))
            else:
                return redirect(reverse('sxw:login'))

ミドルウェアを作成し、settingsに登録します.