本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习

https://www.bilibili.com/video/BV1vt41147K8?p=1

实现功能为:

在商品详情页面,选择想要购买的数量,点击“加入购物车”按钮,实现右上角的购物车数量增加,并且页面其他信息保持不变。

一般处理按钮点击后,需要重新查询刷新整个页面的信息,但是很多需求只是刷新局部或一小部分信息,因此可以通过发送Ajax请求实现,注意ajax请求都是在后台运行的,前台不会展示运行的过程。

Ajax请求过程为:

1. 前端页面发起ajax请求(这里使用jQuery)将数据传递给后端

2. 后端执行请求地址相对应的视图函数,返回json内容

3. ajax执行相应的回调函数。接收返回的json数据并执行后续操作

编辑详情页面的前端js代码

1、jQuery获取标签元素对象为:$('.classname')

2、获取子标签:$('.classname').children('标签名')

3、获取文本内容为:.text()

4、获取值属性为:.val()

5、设置标签值为在获取值的方法中加入参数,该参数就是想要设置成为的值

6、注意点击事件如果想要调用其他的方法,不能直接写成.click(function_name()),还是得写成.click(function (){function_name()}),即在匿名方法中再调用其他的方法

7、isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字。

8、发起Ajax请求写法,$.post('/cart/add/', parameter, function(data){....}) 第一个参数为请求提交的地址,第二个参数为传给后台的数据,第三个参数为回调函数,即后台处理完成后,会调用这个回调函数,参数data为后台返回的数据,在回调函数中,使用返回的数据重新设置页面的部分数据

{% block endfiles %}
<div class="add_jump"></div> <script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js'%}"></script>
<script type="text/javascript">
//计算总价
update_goods_amout()
function update_goods_amout(){
//获取单价
price = $('.show_pirze').children('em').text()
//获取数量
count = $('.num_show').val()
//计算总价
amount = price * count
//刷新界面总价
$('.total').children('em').text(amount.toFixed(2)+'元')
}
//加号点击事件
$('.add').click(function(){
calculate(1)
})
//减号点击事件
$('.minus').click(function(){
calculate(-1)
})
//加减数量
function calculate(num){
//获取原数量
count = $('.num_show').val()
//+-1
count = parseInt(count) + num
if (count <=0){
count = 1
}
//刷新界面
$('.num_show').val(count)
//更新总价
update_goods_amout()
}
//手动输入商品数量
$('.num_show').blur(function(){
//获取数量
count = $(this).val()
//校验数量,
if (isNaN(count) || count.trim().length==0 || parseInt(count) <=0){
//刷新数量
count = 1
$(this).val(parseInt(count))
}
//更新总价
update_goods_amout()
})
//获取add_cart div元素左上角的坐标
var $add_x = $('#add_cart').offset().top;
var $add_y = $('#add_cart').offset().left;
//获取show_count div元素左上角的坐标
var $to_x = $('#show_count').offset().top;
var $to_y = $('#show_count').offset().left; //点击加入购物车的click事件
$('#add_cart').click(function(){
//获取数量
count = $('.num_show').val()
//获取商品ID,手动给加入购物车按钮新增一个属性goods_id
goods_id = $(this).attr('goods_id')
//csrf验证信息
csrf = $('input[name="csrfmiddlewaretoken"]').val()
//组织参数
parameter = {
'goods_id': goods_id,
'count': count,
'csrfmiddlewaretoken': csrf
}
//发起Ajax请求,第三个参数function为回调函数
$.post('/cart/add/', parameter, function(data){
if (data.status == 'S'){
//添加成功
//购物车加入成功的动态效果
$(".add_jump").css({'left':$add_y+80,'top':$add_x+10,'display':'block'})
$(".add_jump").stop().animate(
{'left': $to_y+7,
'top': $to_x+7},
"fast",
function() {
$(".add_jump").fadeOut('fast',function(){
//刷新右上角购物车数量
$('#show_count').html(data.cart_count);
});
});
}
else{
//添加失败
alert(data.errmsg)
}
})
}) </script>
{% endblock endfiles %}

编辑请求提交的URL

编辑cart应用的urls.py文件

from django.urls import path
from .views import CartView, CartAddView urlpatterns = [
path('add/', CartAddView.as_view(), name='add'),
path('', CartView.as_view(), name='cart'),
]

编辑处理请求的类视图

编辑cart应用的view.py文件

1、这里判断用户是否登录时,是手动写的校验,而不是像user应用中继承LoginRequiredMixin,原因是因为如果继承了LoginRequiredMixin,谷歌浏览器按F12打开后台运行情况查看,后台确实会访问重定向到的登录页面,但是由于这里提交的是Ajax请求,前台并不会跳转成登录页面,所以用户体验来说是这个跳转是无效的。

2、获取前台传过来的商品和数量,校验成功后,将其添加至购物车redis数据库中,然后返回新的购物车数据

3、返回的是JsonResponse对象,返回值内容为json格式

from django.views.generic import View
from django.http import JsonResponse
from goods.models import Goods
from django_redis import get_redis_connection class CartAddView(View):
'''加入购物车处理视图'''
def post(self, request):
user = request.user
context = {
'status': 'E',
'errmsg': ''
}
# 判断是否登录
if not user.is_authenticated:
context['errmsg'] = '用户未登录!'
return JsonResponse(context) # 接收数据
goods_id = request.POST.get('goods_id')
count = request.POST.get('count') # 校验数据
# 数据是否完整
if not all([goods_id, count]):
context['errmsg'] = '数据不完整!'
return JsonResponse(context)
# 商品是否存在
try:
goods_id = int(goods_id)
goods = Goods.objects.get(id=goods_id)
except Exception as e:
context['errmsg'] = '用户未登录!'
return JsonResponse(context)
# 数量格式是否正确
try:
count = int(count)
except Exception as e:
context['errmsg'] = '商品数量格式不正确!'
return JsonResponse(context) # 逻辑处理:添加购物车
# 连接redis
connect = get_redis_connection('default')
cart = 'cart_%d'%(user.id)
# 获取原购物车中goods_id的数量
old_count = connect.hget(cart, goods_id)
if old_count:
count += int(old_count)
# 判断是否超过库存
if count > goods.onhand:
context['errmsg'] = '超出库存数量!'
return JsonResponse(context)
# 将新数量保存至数据库
connect.hset(cart, goods_id, count)
# 获取新购物车数量
cart_count = connect.hlen(cart) # 返回数据
context['status'] = 'S'
context['cart_count'] = cart_count
return JsonResponse(context)

DJANGO-天天生鲜项目从0到1-009-购物车-Ajax实现添加至购物车功能的更多相关文章

  1. django天天生鲜项目

    .后台admin管理天天生鲜商品信息 models里 from django.db import modelsfrom tinymce.models import HTMLField #需要pip安装 ...

  2. DJANGO-天天生鲜项目从0到1-007-首页静态化与缓存

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  3. python 天天生鲜项目

    python 天天生鲜项目 django版:https://github.com/Ivy-1996/fresh flask版:https://github.com/Ivy-1996/flask-fre ...

  4. Django之天天生鲜项目

    准备工作 1.配置settings.py内置文件 注意: AUTH_USER_MODEL配置参数要在第一次迁移数据库之前配置,否则可能django的认证系统工作不正常 2.创建应用 3.配置主路由 一 ...

  5. DJANGO-天天生鲜项目从0到1-012-订单-用户订单页面

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  6. DJANGO-天天生鲜项目从0到1-011-订单-订单提交和创建

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  7. DJANGO-天天生鲜项目从0到1-010-购物车-购物车操作页面(勾选+删改)

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  8. DJANGO-天天生鲜项目从0到1-009-搜索功能实现(django-haystack+whoosh+jieba)

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  9. DJANGO-天天生鲜项目从0到1-006-首页-内容展示

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

随机推荐

  1. 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)

    最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...

  2. Zookeeper分布式过程协同技术 - 群首选举

    Zookeeper分布式过程协同技术 - 群首选举 群首概念 群首为集群中服务器选择出来的一个服务器,并被集群认可.设置群首目的在与对客户端所发起的状态变更请求进行排序,包括:create.setDa ...

  3. 入门大数据---Kylin搭建与应用

    由于Kylin官网已经是中文的了,而且写的很详细,这里就不再重述. 学习右转即可. 这里说个遇到的问题,当在Kylin使用SQL关键字时,要加上双引号,并且里面的内容要大写,这个和MySql有点区别需 ...

  4. JDK8--09:全新的时间API

    在JDK8之前,时间有各种问题,最大的问题就是,我们使用的时间格式化类SimpleDateFormat不是线程安全的 为了更准确的说明SimpleDateFormat非线程安全,演示一个并发做时间格式 ...

  5. node:semantic version instruction

    [major].[minor].[patch] MAJOR version when you make incompatible API changes, MINOR version when you ...

  6. npm tip: go to the package's home page

    exec the following order: --- npm home <package name>

  7. JavaScript之DOM的增删改查

    JavaScript的组成: 1. ECMAScript-语法规范 2. Web APIs(浏览器提供的工具) (1).BOM (浏览器对象模型) (2).DOM (文档对象模型) 今天就来讲讲DOM ...

  8. node实现文件属性批量修改(文件名)

    前言 书接上回,我们实现了批量修改文件的时间,但是却没有实现文件名称的批量修改,是因为我也说过,没有界面的话直接在命令行实现显得有点繁琐,所以我们就通过接口+界面的方式来实现我们这个小需求吧.所以,闲 ...

  9. POJ 1852 Ants(贪心)

    POJ 1852 Ants 题目大意 有n只蚂蚁在木棍上爬行,每只蚂蚁的速度都是每秒1单位长度,现在给你所有蚂蚁初始的位置(蚂蚁运动方向未定),蚂蚁相遇会掉头反向运动,让你求出所有蚂蚁都·掉下木棍的最 ...

  10. P3574 FAR-FarmCraft 题解

    题目 In a village called Byteville, there are \(n\) houses connected with \(n-1\) roads. For each pair ...