Django 13购物商城项目(购物车、订单)

1、新建购物车表:axf_cart

建表:模型
在这里插入图片描述

# 购物车
class Cart(models.Model):
    # Foreign Key外键,on_delete=models.CASCADE此值设置,是级联删除,django2必须加这一项
    C_user = models.ForeignKey(AXFUser,on_delete=models.CASCADE)
    C_goods = models.ForeignKey(Goods,on_delete=models.CASCADE)

    C_goods_num = models.IntegerField(default=1)
    C_is_select = models.BooleanField(default=True)

    class Meta:
        db_table = 'axf_cart'

迁移:

python manage.py makemigrations
python manage.py migrate

2、中间件:用户登录状态获取

新建文件及内容:
在这里插入图片描述

# 这里和上面截图里的代码不同,以这里为准

from App.models import AXFUser
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin

# 返回 json
R_LOGIN_JSON = [
    '/axf/addtocart/',
    '/axf/subtocart/',

]

# 返回 重定向
R_LOGIN = [
    '/axf/cart/',

]


class LoginMiddleware(MiddlewareMixin):
    def process_request(self, request):

        if request.path in R_LOGIN_JSON:
            user_id = request.session.get('user_id')
            # 已登录
            if user_id:
                try:
                    user = AXFUser.objects.get(pk=user_id)
                    request.user = user

                except:
                    data = {
                        "status": 301,
                        "msg": "用户状态失效"
                    }
                    return JsonResponse(data=data)
            # 未登录
            else:
                data = {
                    "status": 301,
                    "msg": "用户状态失效"
                }
                return JsonResponse(data=data)
        if request.path in R_LOGIN:
            user_id = request.session.get('user_id')
            # 已登录
            if user_id:
                try:
                    user = AXFUser.objects.get(pk=user_id)
                    request.user = user

                except:
                    return redirect(reverse("axf:login"))
            # 未登录
            else:
                return redirect(reverse("axf:login"))

在setting.py里面配置:
在这里插入图片描述

 'middleware.middleware.LoginMiddleware',

3、matket里 加减号操作购物车

tenplates/mian/ market.html
在这里插入图片描述
axf/main/css/ market.css

/* 原有基础上添加 */

.subShopping ,.addShopping{
    font-size: 0.4rem;
    font-weight: 100;
}

axf/main/js/ market.js
在这里插入图片描述

    $(".subShopping").click(function () {
        var $sub = $(this);

        // attr获取html标签的属性
        var goodsid = $sub.attr("goodsid");

        $.get('/axf/subtocart/', {'goodsid': goodsid}, function (data) {
            console.log(data);
            if (data['status'] === 302) {
                window.open('/axf/login/', target = "_self");
            } else if (data["status"] === 200) {
                console.log('减一成功');
                // $add.next('span')找到.subShopping下面最近的span
                $sub.next('span').html(data['C_goods_num']);
            } else if (data['msg']=== 0){
                console.log('里面没有数据');
            }
        });
    });
    $(".addShopping").click(function () {
        var $add = $(this);

        // attr获取html标签的属性
        var goodsid = $add.attr("goodsid");

        $.get('/axf/addtocart/', {'goodsid': goodsid}, function (data) {
            console.log(data);
            if (data['status'] === 302) {
                window.open('/axf/login/', target = "_self");
            } else if (data["status"] === 200) {
                console.log('添加成功');
                // $add.prev('span')找到.addShopping上面最近的span
                $add.prev('span').html(data['C_goods_num']);
            }
        });
    });

路由:
在这里插入图片描述
视图:
在这里插入图片描述

def add_to_cart(request):
    goodsid = request.GET.get('goodsid')

    # 获取购物车里的数据
    carts = Cart.objects.filter(C_user=request.user).filter(C_goods_id=goodsid)
    print(request.user)
    # 有数据+1
    if carts.exists():
        c_obj = carts.first()
        c_obj.C_goods_num = c_obj.C_goods_num + 1

    # 没有数据创建新的
    else:
        c_obj = Cart()
        c_obj.C_goods_id = goodsid
        c_obj.C_user = request.user

    c_obj.save()

    data = {
        'msg': 1,
        'status': 200,
        "C_goods_num": c_obj.C_goods_num,
    }

    return JsonResponse(data=data)


def sub_to_cart(request):
    goodsid = request.GET.get('goodsid')
    carts = Cart.objects.filter(C_user=request.user).filter(C_goods_id=goodsid)
    data = {
        'msg': 0,
    }
    if carts.exists():
        c_obj = carts.first()
        if c_obj.C_goods_num >= 1:
            c_obj.C_goods_num = c_obj.C_goods_num - 1
            c_obj.save()
            data = {
                'msg': 1,
                'status': 200,
                "C_goods_num": c_obj.C_goods_num,
            }
        if c_obj.C_goods_num == 0:
            Cart.objects.filter(pk=c_obj.id).delete()

    return JsonResponse(data=data)

访问:
在这里插入图片描述

4、购物车页面

cart.html

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

{% block ext_css %}
    {{ block.super }}
    <link rel="stylesheet" href="{% static 'axf/main/css/cart.css' %}">
{% endblock %}
{% block ext_js %}
    {{ block.super }}
    <script type="text/javascript" src="{% static 'axf/main/js/cart.js' %}"></script>
{% endblock %}
{% block content %}
    <div id="cart">
        <h3>购物车</h3>
        <div class="full">
            <section>
                <ul>
                    <li>&nbsp;&nbsp;人:&nbsp;小明</li>
                    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;话:&nbsp;155451346343</li>
                    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址:&nbsp;北京</li>
                </ul>
                <div class="bill">
                    <p>闪送超市</p>
                    <p>0元起送,满3010</p>
                    <a href="#">凑单专区</a>
                </div>
                <div class="delivery">
                    <span>收货时间</span>
                    <span>一小时送达</span>
                    <span><a href="#">可预订&gt;</a></span>
                </div>
                <div class="delivery">
                    <span>收货备注</span>
                    <input type="text" placeholder="可输入100字">

                </div>
                <ul>
                    {% for cart in carts %}
                        <li class="menuList" cartid="{{ cart.id }}" goodsid="{{ cart.C_goods_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="presenPrice">{{ 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>
                <div class="payTheBill">
                    <div class="confirm">
                        <span>
                            <span>

                            </span>
                        </span>
                    </div>
                    <p>
                        <span>全选</span>
                        <span>共计:</span>
                        <span>0</span>
                    </p>
                    <a href="#">下单</a>
                </div>

            </section>

        </div>
    </div>

{% endblock %}

cart.css

/*底部图标*/
footer .cart span {
    background: url(/static/img/cart_selected.png) no-repeat;
    background-size: 0.513889rem;
}

footer .cart dd {
    color: orange;
}

/*内容*/
#cart {
    padding: 1.5rem 0;
    z-index: +15;
    width: 100%;
    background: #fafafa;
    overflow: hidden;
}

h3 {
    text-align: center;
    position: fixed;
    width: 100%;
    border-bottom: 0.04rem solid lightgray;
    line-height: 1.5rem;
    background: yellow;
    top: 0;
    z-index: +100;
}

.full > section {
    background: lightpink;
}

.full > section > ul {
    border: 0.2rem dashed lightgreen;
    border-width: 0.1rem 0;
    margin-bottom: 0.2rem;
}

.full > section > ul > li {
    padding-left: 0.3rem;
    line-height: 0.8rem;
    font-size: 0.375rem;
}

.clear:after {
    content: "";
    display: block;
    visibility: hidden;
    clear: both;
    height: 0;
}

.full > section > ul > li > div > p:last-child {
    float: right;
    width: 78%;
}

.full > section > ul > li > div > p:last-child > span {
    padding: 0.15rem;
}

.infoJustify {
    float: left;
    width: 20%;
    height: 0.8rem;
    overflow: hidden;
    text-align: justify;
}

.infoJustify b {
    display: inline-block;
}

.change {
    float: right;
    padding-right: 0.2rem;
}

/*闪送超市*/
.bill {
    line-height: 0.75rem;
    position: relative;
    border-bottom: 0.04rem solid lightgreen;
}

.bill > p {
    padding: 0 0.3rem;
    font-size: 0.3rem;
    color: #d35a00;

}

.bill > p:first-child:before {
    width: 0.2rem;
    height: 0.3rem;
    background: yellow;
    content: ".";
    color: yellow;
    margin-right: 0.2rem;

}

.bill > a {
    border: 0.05rem solid orangered;
    position: absolute;
    border-radius: 0.3rem;
    padding: 0 0.3rem;
    font-size: 0.35rem;
    line-height: 0.65rem;
    top: 0.2rem;
    right: 0.5rem;
}

/*收货时间,收货备注*/
.delivery {
    line-height: 1.5rem;
    border-bottom: 0.04rem solid lightgray;
    font-size: 0.4rem;
    padding: 0 0.3rem;
}

.delivery > span:first-child {
    padding-right: 0.3rem;

}

.delivery > span:nth-child(2) {
    color: orangered;
}

.delivery > span:last-child {
    float: right;

}

.delivery > input {
    height: 0.8rem;
    line-height: 0.8rem;
    border-radius: 0.1rem;
    border-width: 0.04rem;
    width: 70%;

}

.menuList {
    border-bottom: 0.04rem solid lightgray;
    height: 2.5rem;
    position: relative;

}

.confirm {
    padding: 0.95rem 0;
    width: 15%;
    height: 2.5rem;
    display: inline-block;
    box-sizing: border-box;
    text-align: center;
    float: left;
}

.confirm > span {
    box-sizing: border-box;
    border: 0.04rem solid orange;
    background: white;
    display: inline-block;
    width: 0.6rem;
    height: 0.6rem;
    overflow: hidden;
    border-radius: 50%;
    line-height: 0.6rem;
}

.confirm > span > span {
    background: yellow;
    font-size: 0.5rem;
    display: block;

}

.menuList > a {
    width: 84%;
    display: inline-block;
    font-size: 0.4rem;
    line-height: 1rem;

}

.menuList > a > img {
    margin-top: 0.25rem;
    width: 25%;
    height: 100%;
    float: left;
}

.menuList > a > p {
    width: 70%;
    height: 1rem;
    float: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /*去除a标签的连接蓝色属性 text-decoration设置文本修饰属性*/
    text-decoration: none;
    color: #333;
}

.menuList > section {
    position: absolute;
    right: 0.4rem;
    bottom: 0.4rem;
    height: 0.75rem;
    border-radius: 1rem;
}

.menuList > section > button {
    background: white;
    border: 1px solid orange;
    border-radius: 1111px;
    color: red;
    display: inline-block;
    text-align: center;
    line-height: 0.65rem;
    font-weight: 900;
    width: 0.75rem;
    height: 0.75rem;
}

.menuList > section > span {
    display: inline-block;
    width: 0.5rem;
    text-align: center;
    line-height: 0.5rem;
    font-size: 0.4rem;

}

.presenPrice:before {
    content: "¥";
    font-size: 0.33rem;

}

/*下单,付钱*/
.payTheBill {
    height: 1.5rem;
    position: relative;
}

.payTheBill .confirm {
    width: 10%;
    padding-top: 0.4rem;
    padding-left: 0.4rem;

}

.payTheBill > p {
    line-height: 1.5rem;
    text-indent: 0.3rem;

}

.payTheBill > p > span:first-child {
    padding-right: 0.8rem;

}

.payTheBill > p > span:last-child {
    padding-left: 0.3rem;
    color: red;

}

.payTheBill > p > span:last-child:before {
    content: "¥";
    font-size: 0.35rem;
}

.payTheBill > a {
    padding: 0 0.7rem;
    line-height: 1.5rem;
    background: yellow;
    position: absolute;
    right: 0;
    top: 0;
}


cart.js

$(function () {
    $(".confirm").click(function () {
        var $confirm = $(this);
        var $li = $confirm.parents("li");
        var cartid = $li.attr('cartid');
        $.getJSON("/axf/changecart/", {'cartid': cartid}, function (data) {
            console.log(data);
            if (data['status'] === 200) {
                if (data['C_is_select']) {
                    $confirm.find("span").find("span").html("√");

                } else {
                    $confirm.find("span").find("span").html("");
                }
            }
        });
    });
    $(".subShopping").click(function () {
        var $sub = $(this);
        var $li = $sub.parents("li");
        var goodsid = $li.attr("goodsid");
        $.get('/axf/subtocart/', {'goodsid': goodsid}, function (data) {
            console.log(data);
            if (data['status'] === 200) {
                if (data['C_goods_num'] > 0) {
                    $sub.next('span').html(data['C_goods_num']);
                } else {
                    $li.remove();
                }
            }
        });
    });
    $(".addShopping").click(function () {
        var $add = $(this);
        var $li = $add.parents("li");
        var goodsid = $li.attr("goodsid");
        $.get('/axf/addtocart/', {'goodsid': goodsid}, function (data) {
            if (data['status'] === 200) {
                $add.prev('span').html(data['C_goods_num']);
            }
        });
    });
});
发布了87 篇原创文章 · 获赞 20 · 访问量 1624

猜你喜欢

转载自blog.csdn.net/a__int__/article/details/103675536