本项目基于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. Docker 快速入门(一)- 情况介绍和安装

    欢迎您! 很高兴您想学习 Docker . 这个页面包含了如何开始使用 Docker 的循序渐进的说明. Docker 快速入门培训模块教你如何: 设置 Docker 环境(在本页) 构建并运行您的镜 ...

  2. python文件处理-将图像根据坐标画矩形标记

    内容涉及:文件遍历,选取csv后缀文件,用cv操作图片 import csv import os import sys import numpy as np import copy import sh ...

  3. nginx web服务器概念了解 配置

    服务器 服务器 服务器是一种提供高效计算的机器,与普通的PC主机相比,具有可观的稳定性,高并发性,可扩展性. 互联网任何一个应用都是以服务器为基础设施的,没有服务器我们就无法访问网络上的任何内容,只能 ...

  4. dart快速入门教程 (2)

    2.变量和数据类型 2.1.变量和常量 变量通俗的说就是可以变化的量,作用就是用来存储数据,你可以把一个变量看作是一个水果篮,里面可以装苹果.梨.香蕉等,常量就是一个固定的值,和变量是相对的,变量可以 ...

  5. 【Spring注解驱动开发】BeanPostProcessor在Spring底层是如何使用的?看完这篇我懂了!!

    写在前面 在<[String注解驱动开发]面试官再问你BeanPostProcessor的执行流程,就把这篇文章甩给他!>一文中,我们详细的介绍了BeanPostProcessor的执行流 ...

  6. https http 混合访问_https 页面中引入 http 资源的解决方式

    解决android 5.0 webview不能加载http与https混合内容的问题 在使用WebView加载https资源文件时,如果认证证书不被Android认可,那么会出现无法成功加载对应资源问 ...

  7. css 分割线样式_css实现文章分割线的多种方法总结

    这篇文章整理css如何实现文章分割线的多种方式,分割线在页面中可以起到美化作用,那么就来看看使用css实现分割线样式的多种方法.效果如下: 方式一:单个标签实现分隔线: html: <div c ...

  8. i++ & ++i不看字节码是真的难懂

    package club.interview.base; /** * ++i 先"++"后赋值 * i++ 先赋值后"++" * i++ 局部变量表的值会改变, ...

  9. 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G

    [USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...

  10. salesman,动态规划带一点点贪心。

    题目直接链接 分析一下: 这题题意还是比较明白的(少见的一道中文题),他的意思就是:有这么一个无向图:保证联通且点与点直接有唯一的简单路径(说白了就是棵树,根节点是1),每个节点有一个权值(有正有负) ...