# 购物车
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
# 这里和上面截图里的代码不同,以这里为准
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"))
'middleware.middleware.LoginMiddleware',
tenplates/mian/ market.html
axf/main/css/ market.css
/* 原有基础上添加 */
.subShopping ,.addShopping{
font-size: 0.4rem;
font-weight: 100;
}
$(".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)
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>收 货 人: 小明</li>
<li>电 话: 155451346343</li>
<li>地 址: 北京</li>
</ul>
<div class="bill">
<p>闪送超市</p>
<p>0元起送,满30送10</p>
<a href="#">凑单专区</a>
</div>
<div class="delivery">
<span>收货时间</span>
<span>一小时送达</span>
<span><a href="#">可预订></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']);
}
});
});
});