接着上期代码框架,开发第5个功能,兑换物品管理,再增加一个学习兑换物品表,主要用来维护兑换物品,所需积分,物品状态等信息,还有一个积分流水表,完成任务奖励积分,兑换物品消耗积分。
要想激励一个人的学习动力,最好能有实际的奖励,完成任务后,系统应给予一定的奖励,如积分或实际物品等。
目前系统考虑使用积分奖励,然后这些积分积累多了就可以兑换实际物品,这些奖励可以激励用户持续学习。
第一步:编写第5个功能-兑换物品管理
1,编辑模型文件:
./mysite/study_system/models.py:
class StudyExchangeItem(models.Model): item_id = models.AutoField(primary_key=True, verbose_name='兑换物品ID') item_name = models.CharField(max_length=200, verbose_name='兑换物品名称', blank=True) item_points = models.IntegerField(verbose_name='兑换积分数') item_description = models.TextField(verbose_name='兑换物品描述', blank=True) item_status = models.CharField(max_length=20, verbose_name='兑换物品状态:0-未兑换, 1-已兑换') created_time = models.DateTimeField(verbose_name='创建时间') update_time = models.DateTimeField(verbose_name='更新时间') created_by = models.ForeignKey(StudyUser, on_delete=models.CASCADE, verbose_name='创建者ID') class Meta: verbose_name = '兑换物品表' verbose_name_plural = '兑换物品表' # 用于模型的数据库表的名称 db_table = "study_exchange_items" def __str__(self): return self.item_name class StudyPoint(models.Model): point_id = models.IntegerField(primary_key=True, verbose_name='积分ID,使用任务ID或物品ID') user_id = models.ForeignKey(StudyUser, on_delete=models.CASCADE, verbose_name='用户ID') point_type = models.IntegerField(verbose_name='积分类型') points_nums = models.IntegerField(verbose_name='积分数') point_name = models.CharField(max_length=200, verbose_name='积分说明') created_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) class Meta: verbose_name = '积分流水表' verbose_name_plural = '积分流水表' # 用于模型的数据库表的名称 db_table = "study_points" def __str__(self): return self.point_name
2,编辑urls配置文件:
./mysite/study_system/urls.py
# 兑换物品管理url path('item/getExchangeItemList/', views.getExchangeItemList, name='getExchangeItemList'), path('item/toNewExchangeItem/', views.toNewExchangeItem, name='toNewExchangeItem'), path('item/addExchangeItem/', views.addExchangeItem, name='addExchangeItem'), path('item/exchangeItem/', views.exchangeItem, name='exchangeItem'),
3,编辑视图文件:
./mysite/study_system/views.py
def getExchangeItemList(request): ''' @方法名称: 获取兑换物品列表 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-10-10 ''' # 响应容器 rsp_dict = {} # 获取当前用户名 username = request.session.get('username') # 根据用户名获取用户对象 cur_user = StudyUser.objects.get(username=username) print('根据用户名查询用户对象:' + str(cur_user)) user_list = [cur_user] # 如果当前用户是:3-学生,则查找对应辅导员用户 if cur_user.role == 3: parent_id = cur_user.parent_id # 根据用户ID获取用户对象 parent_user = StudyUser.objects.get(user_id=parent_id) print('根据用户ID获取用户对象:' + str(parent_user)) user_list = [cur_user, parent_user] # 获取待完成任务列表,限制发布人 data_list = StudyExchangeItem.objects.filter(created_by__in=user_list).order_by('-pk') rsp_dict['data_list'] = data_list context_object_name = "exchange_item_list" template_name = "study_system/home.html" rsp_dict['html_file'] = 'study_system/item/exchangeItemList.html' rsp_dict['context_object_name'] = context_object_name return render(request, template_name, rsp_dict) def toNewExchangeItem(request): ''' @方法名称: 跳转到新增兑换物品视图 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-10-10 ''' rsp_dict = {} rsp_dict["pageTitle"] = "新增兑换物品" rsp_dict['html_file'] = 'study_system/item/addExchangeItem.html' return render(request, "study_system/home.html", rsp_dict) def addExchangeItem(request): ''' @方法名称: ajax请求, 表单视图,新增兑换物品 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-10-10 ''' # 初始化响应容器 rsp_dict = {"result": "error", "errorMsg": "系统错误"} # 是否ajax请求 if request.is_ajax(): try: rest = request.POST item_name = rest['itemName'] item_points = int(rest['itemPoints']) item_description = rest['itemDescription'] item_status = rest['itemStatus'] # 获取当前用户名 username = request.session.get('username') # 根据用户名获取用户对象 cur_user = StudyUser.objects.get(username=username) print('根据用户名查询用户对象:' + str(cur_user)) # 创建者ID,使用 StudyUser 对象赋值 created_by = cur_user # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) print('当前日期时间:' + str(work_date)) # 创建对象并保存到数据库 studyExchangeItem = StudyExchangeItem(item_name=item_name, item_points=item_points, item_description=item_description, item_status=item_status, created_time=work_date, update_time=work_date, created_by=created_by) # 保存到数据库是否成功 studyExchangeItem.save() rsp_dict["result"] = "success" except Exception as e: rsp_dict["errorMsg"] = "新增兑换物品保存到数据库失败." # 成功与否都返回json数据格式 return JsonResponse(rsp_dict)
兑换物品,更新物品状态,同时添加消耗积分流水。
def exchangeItem(request): ''' @方法名称: ajax请求, 表单视图,更新兑换物品-已兑换 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-10-10 ''' # 初始化响应容器 rsp_dict = {"result": "error", "errorMsg": "系统错误"} # 是否ajax请求 if request.is_ajax(): try: rest = request.GET item_id = int(rest['itemId']) # 获取当前用户名 username = request.session.get('username') # 根据用户名获取用户对象 cur_user = StudyUser.objects.get(username=username) print('根据用户名查询用户对象:' + str(cur_user)) # 学生用户总积分值,需要取学生用户,关联的属性表的值 studyUserAttribute = StudyUserAttribute.objects.filter(user_id=cur_user) total_points = studyUserAttribute[0].total_points print("学生用户总积分值:" + str(total_points)) # 根据ID查询对象数据, filter 返回的是列表对象,一个对象取list.0 studyExchangeItem = StudyExchangeItem.objects.filter(item_id=item_id) item_name = studyExchangeItem[0].item_name item_points = studyExchangeItem[0].item_points print("兑换物品所需积分值:" + str(item_points)) # 比较 用户总积分值 是否大于等于 兑换物品所需积分值 if int(total_points) >= int(item_points): # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) print('当前日期时间:' + str(work_date)) # 兑换积分数 points_nums = 0 - int(item_points) # 插入 积分流水表 # 积分ID, 使用任务ID或物品ID point_id = item_id # 用户ID user_id = cur_user # 积分类型,1-奖励, 0-兑换, 2-处罚 point_type = 0 # 积分说明,任务名或兑换物品名 point_name = item_name # 创建对象并保存到数据库 studyPoint = StudyPoint(point_id=point_id, user_id=user_id, point_type=point_type, points_nums=points_nums, point_name=point_name, created_time=work_date) # 保存到数据库是否成功 studyPoint.save() # 更新兑换物品表数据状态:1-已兑换 studyExchangeItem.update(item_status='1', update_time=work_date) # 更新属性表,总积分值数 total_points = int(total_points) - int(item_points) studyUserAttribute.update(total_points=total_points, update_time=work_date) rsp_dict["result"] = "success" else: rsp_dict["errorMsg"] = "兑换物品失败,用户总积分值不足!" except Exception as e: rsp_dict["errorMsg"] = "更新兑换物品,保存到数据库失败." # 成功与否都返回json数据格式 return JsonResponse(rsp_dict)
4,编辑页面模板代码:
4.1. 兑换物品列表页面
./mysite/study_system/templates/study_system/item/exchangeItemList.html
<script type="text/javascript"> //兑换物品 function exchangeItem(itemId) { //alert(itemId); $.get("/study_system/item/exchangeItem?itemId=" + itemId, function (data) { if ("success" == data.result) { alert("兑换成功"); window.location.reload(); } else { alert("兑换失败:" + data.errorMsg); } }); } </script> {% if request.session.role == 1 or request.session.role == 2 or request.session.role == 4 %} {# 【角色 :1-系统管理员 】#} {# 【角色 :2-辅导员 】#} {# 【角色 :4-自导自学 】#} <div> <a href="/study_system/item/toNewExchangeItem/" class="btn btn-default btn-lg btn-block btn-a" style="color: #EC5F13;">新增兑换物品</a> </div> {% endif %} <!-- 结果显示区 --> <div id="dataList"> {% if data_list %} {% for exchangeItem in data_list %} <ul class="dataCardList"> {% if request.session.role == 1 or request.session.role == 2 or request.session.role == 4 %} {# 【角色 :1-系统管理员 】#} {# 【角色 :2-辅导员 】#} {# 【角色 :4-自导自学 】#} <li class="btn-group btn-group-justified"> <a href="#" class="btn btn-default btn-lg">修改</a> <a href="#" class="btn btn-default btn-lg">删除</a> </li> {% endif %} <li>【兑换物品ID :{{ exchangeItem.item_id }}】</li> <li>【兑换物品名称 :{{ exchangeItem.item_name }}】</li> <li>【兑换积分数 :{{ exchangeItem.item_points }} 积分】</li> <li>【兑换物品描述 :{{ exchangeItem.item_description }}】</li> <li>【创建用户 :{{ exchangeItem.created_by.username }}】</li> <li>【创建时间 :{{ exchangeItem.update_time|date:'Y-m-d H:i:s' }}】</li> {% if request.session.role == 1 or request.session.role == 3 or request.session.role == 4 %} {# 【角色 :1-系统管理员 】#} {# 【角色 :3-学生 】#} {# 【角色 :4-自导自学 】#} <li> {% if exchangeItem.item_status == "0" %} <a href="javascript:exchangeItem('{{ exchangeItem.item_id }}')" class="btn btn-default btn-lg btn-block btn-a">可兑换</a> {% elif exchangeItem.item_status == "1" %} <a href="#" class="btn btn-default btn-lg btn-block disabled" style="background-color: #DCDCDC;;font-size: 1.2em;color: #008B45" role="button">已兑换</a> {% endif %} </li> {% endif %} </ul> {% endfor %} {% else %} <strong>查无记录</strong> {% endif %} </div>
4.2. 新增兑换物品页面
./mysite/study_system/templates/study_system/item/addExchangeItem.html
<script type="text/javascript"> function addExchangeItem() { var itemName = $("input[name='itemName']").val(); var itemPoints = $("input[name='itemPoints']").val(); var itemDescription = $("textarea[name='itemDescription']").val(); var itemStatus = $("select[name='itemStatus']").val(); var csrf_token = '{{ csrf_token }}'; $.post("/study_system/item/addExchangeItem/", { 'itemName': itemName, 'itemPoints': itemPoints, 'itemDescription': itemDescription, 'itemStatus': itemStatus, // 将token值放到请求数据部分,token的键必须是 csrfmiddlewaretoken 'csrfmiddlewaretoken': csrf_token, }, function (data) { if ("success" == data.result) { alert("新增成功"); window.location.href = "/study_system/item/getExchangeItemList/"; } else { alert("新增失败:" + data.errorMsg); } }); } </script> <div class="container"> <h1 class="text-center">新增兑换物品</h1> <form action="/study_system/item/addExchangeItem/" method="post" class="form-horizontal" role="form"> {% csrf_token %} <div class="form-group"> <label for="itemName" class="col-sm-2 control-label">任务名称</label> <div class="col-sm-10"> <input type="text" class="form-control" name="itemName" id="itemName" placeholder="请输入兑换物品名称"> </div> </div> <div class="form-group"> <label for="itemDescription" class="col-sm-2 control-label">兑换物品描述</label> <div class="col-sm-10"> <textarea name="itemDescription" id="itemDescription" class="form-control" rows="4"></textarea> </div> </div> <div class="form-group"> <label for="itemPoints" class="col-sm-2 control-label">兑换积分数</label> <div class="col-sm-10"> <input type="text" class="form-control" name="itemPoints" id="itemPoints" placeholder="请输入兑换积分数"> </div> </div> <div class="form-group"> <label for="itemStatus" class="col-sm-2 control-label">兑换物品状态</label> <div class="col-sm-10"> <select class="form-control" name="itemStatus" id="itemStatus"> <option value="0" selected="selected">0-未兑换</option> </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <a href="javascript:addExchangeItem()" class="btn btn-default btn-lg btn-block btn-a">提交保存</a> </div> </div> </form> </div>
第二步:运行测试-兑换物品管理功能
1,登录用户后,点击查看兑换物品列表页面


点击可兑换物品,如果用户积分充足,则兑换成功,更新物品状态。


-------------------------------------------------end -------------------------------------------------