Django+DRF+Vue+Mysql+Redis OUC软件工程作业

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: Django+DRF+Vue+Mysql+Redis OUC软件工程作业

前端:html+css+js+Vue+Element-ui

后端:Django+DRF+celery+haystack+django_crontab

数据库:Mysql+Redis

一些技术和功能:


为session、短信验证码、用户浏览记录、购物车、异步任务队列 创建缓存

whoosh搜索引擎

异步任务队列 用于发送邮件、短信

定时任务 定时更新静态页面、刷新日志等

腾讯云短信服务

chatGPT客服(New)

支付宝沙盒

客服群聊

数据库乐观锁

页面静态化

JWT认证

发货地址、不同的商品的详情、售后服务等都可以通过后台设置

自选CPU、内存、显卡

"点击此处确认验证邮箱"

对于未登录的用户,购物车数据使用浏览器cookie保存 登陆后合并购物车 对于已登录的用户,购物车数据在后端使用Redis保存

效果如下:

代码过多,这里只展示一部分,欢迎感兴趣的小伙伴一起讨论学习:

import os
from alipay import AliPay
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from MyApps.orders.models import OrderInfo
from MyApps.payment.models import Payment
from django.conf import settings
class PaymentView(APIView):
    """
    支付
    """
    permission_classes = (IsAuthenticated,)
    def get(self, request, order_id):
        """
        获取支付链接
        """
        # 判断订单信息是否正确
        try:
            order = OrderInfo.objects.get(order_id=order_id, user=request.user,
                                          pay_method=OrderInfo.PAY_METHODS_ENUM["ALIPAY"],
                                          status=OrderInfo.ORDER_STATUS_ENUM["UNPAID"])
        except OrderInfo.DoesNotExist:
            return Response({'message': '订单信息有误'}, status=status.HTTP_400_BAD_REQUEST)
        # 构造支付宝支付链接地址
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys",
                                                     "app_private_key.pem")).read(),
            # app_private_key_string=settings.app_private_key_string,
            alipay_public_key_string=open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'keys',
                                                       'alipay_public_key.pem')).read(),
            # alipay_public_key_string=settings.alipay_public_key_string,  # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,
            total_amount=str(order.total_amount),
            subject="联想商城%s" % order_id,
            return_url="http://localhost:63342/BMyStore/front_end_pc/pay_success.html",
        )
        # 需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        # 拼接链接返回前端
        alipay_url = settings.ALIPAY_URL + "?" + order_string
        return Response({'alipay_url': alipay_url})
# 支付宝回调函数接口 put /payment/status/?支付宝参数
class PaymentStatusView(APIView):
    def put(self, request):
        # 接收参数,效验参数
        # 构造支付宝支付链接地址
        alipay_req_data = request.query_params
        if not alipay_req_data:
            return Response({"message": "缺少参数"}, status=status.HTTP_400_BAD_REQUEST)
        alipay_req_dict = alipay_req_data.dict()
        sign = alipay_req_dict.pop("sign")
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                     "keys/app_private_key.pem")).read(),
            alipay_public_key_string=open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                       "keys/alipay_public_key.pem")).read(),
            # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )
        result = alipay.verify(alipay_req_dict, sign)
        # 保存数据,保存支付结果数据
        if result:
            order_id = alipay_req_dict.get("out_trade_no")
            trade_id = alipay_req_dict.get("trade_no")
            # 修改订单状态
            Payment.objects.create(
                order_id=order_id,
                trade_id=trade_id
            )
            OrderInfo.objects.filter(order_id=order_id).update(status=OrderInfo.ORDER_STATUS_ENUM["UNCOMMENT"])
            print('支付成功!')
            return Response({"trade_id": trade_id})
        return Response({"message": "参数有误"}, status=status.HTTP_400_BAD_REQUEST)
from django_filters.rest_framework import DjangoFilterBackend
from drf_haystack.viewsets import HaystackViewSet
from rest_framework.filters import OrderingFilter
from rest_framework.generics import ListAPIView, CreateAPIView, DestroyAPIView, RetrieveAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from MyApps.goods import models
from MyApps.goods.models import SKU, GoodsCategory, Collect, Comment1, SKUImage
from MyApps.goods.serializers import SKUSerializer, SKUIndexSerializer, CollectSerializer, Comment1Serializer
from rest_framework.permissions import IsAuthenticated
from django_redis import get_redis_connection
from rest_framework.filters import BaseFilterBackend
from django_filters import FilterSet, filters
class SKUListView(ListAPIView):
    """
    sku列表数据
    """
    serializer_class = SKUSerializer
    # 分页与排序
    filter_backends = (OrderingFilter,)
    ordering_fields = ("create_time", "price", "sales")
    def get_queryset(self):
        category_id = self.kwargs["category_id"]
        return SKU.objects.filter(category_id=category_id, is_launched=True)
class SKUSearchViewSet(HaystackViewSet):
    """
    SKU搜索
    """
    index_models = [SKU]
    serializer_class = SKUIndexSerializer
    # 分页与排序
    # filter_backends = (OrderingFilter,)
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        ordering_fields = ("create_time", "price", "sales")
        od = request.query_params.get("ordering", None)
        if od in ordering_fields:
            queryset = queryset.order_by(od)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
class CategoriesView(APIView):
    """获取当前分类信息"""
    def get(self, request, pk):
        """
        1.获取前端数据
        2. 查询当前三级分类信息
        3.通过三级分类信息获取一二集分类
        4. 返回
        :param request:
        :return:
        """
        cat3 = GoodsCategory.objects.get(id=pk)  # 获取三级
        cat2 = cat3.parent  # 自关联获取二级,
        cat1 = cat2.parent  # 自关联获取一级
        # 返回数据
        return Response({
            "cat1": cat1.name,
            "cat2": cat2.name,
            "cat3": cat3.name
        })
class GetGoodsView(APIView):
    """获取当前分类信息"""
    def get(self, request, pk):
        SKU1 = models.SKU.objects.filter(pk=pk).first()
        comment_count = SKU1.goods.comment_count
        collect_count = SKU1.goods.collect_count
        goods_id = SKU1.goods_id
        # 返回数据
        return Response({"goods_id": goods_id, 'comment_count': comment_count, 'collect_count': collect_count})
class IsCollectedView(APIView):
    def post(self, request):
        print(request.data)
        sku_id = int(request.data.get("sku_id", -5))
        user_id = request.data.get("user_id", 1)
        if sku_id == -5:
            return Response({"res_data": 0})
        collecs = models.Collect.objects.filter(user_id=user_id)
        sku_id_list = [i.sku_id for i in collecs]
        print(sku_id in sku_id_list)
        res = 0
        if sku_id in sku_id_list:
            res = 1
        return Response({"res_data": res})
##################################
class MyPageNumberPagination(PageNumberPagination):
    page_size_query_param = 'size'
    page_size = 10
    max_page_size = 100
class CommentFilterSet(FilterSet):
    goods = filters.NumberFilter(field_name='goods', required=True)
    class Meta:
        model = models.Comment1
        fields = ['goods']
class Comment1View(ListAPIView, GenericViewSet):
    filter_backends = [DjangoFilterBackend]
    filterset_class = CommentFilterSet
    queryset = models.Comment1.objects
    serializer_class = Comment1Serializer
################################################
class SelfFilterBackend(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        return queryset.filter(user=request.user)
class CollectViewSet(ListAPIView, CreateAPIView, GenericViewSet):
    permission_classes = [IsAuthenticated]
    filter_backends = [SelfFilterBackend, DjangoFilterBackend]
    pagination_class = MyPageNumberPagination
    # 当前登录用户的所有收藏记录
    queryset = models.Collect.objects
    serializer_class = CollectSerializer
    def perform_create(self, serializer):
        user = self.request.user
        instance = Collect.objects.filter(user=user, **serializer.validated_data).first()
        if not instance:
            instance = serializer.save(user=user)
            instance.sku.goods.collect_count += 1
            instance.sku.goods.save()
            return Response({"message": 'ok', 'data': {'active': True}})
        else:
            instance.delete()
            instance.sku.goods.collect_count -= 1
            instance.sku.goods.save()
            return Response({"message": 'ok', 'data': {'active': False}})
class HotSkus(ListAPIView):
    serializer_class = SKUSerializer
    # 分页与排序
    filter_backends = (OrderingFilter,)
    ordering_fields = ("sales", "create_time", "price")
    def get_queryset(self):
        category_id = self.kwargs["category_id"]
        return SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
class ImgListView(APIView):
    def get(self, request):
        s_id = request.query_params.get("sku_id")
        img_list = SKUImage.objects.filter(sku_id=s_id)
        img_list = [i.image.path.split("BMyStore\\")[1] for i in img_list]
        return Response({"img_list": img_list})

有些代码写的略显丑陋 不过能跑就不改了 哈哈


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
16天前
|
缓存 NoSQL 关系型数据库
13- Redis和Mysql如何保证数据⼀致?
该内容讨论了保证Redis和MySQL数据一致性的几种策略。首先提到的两种方法存在不一致风险:先更新MySQL再更新Redis,或先删Redis再更新MySQL。第三种方案是通过MQ异步同步以达到最终一致性,适用于一致性要求较高的场景。项目中根据不同业务需求选择不同方案,如对一致性要求不高的情况不做处理,时效性数据设置过期时间,高一致性需求则使用MQ确保同步,最严格的情况可能涉及分布式事务(如Seata的TCC模式)。
43 6
|
1月前
|
关系型数据库 MySQL 数据库
django4版本提示 django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.26)
在学习Django时,用户遇到`django.db.utils.NotSupportedError`,提示需要MySQL 8.0.25或更高版本,但其系统上是5.7.26。为解决这个问题,用户决定不升级MySQL,而是选择注释掉Django源码中的数据库版本检查。通过Python命令行找到Django安装路径,进入`db/backends/base/base.py`,注释掉`self.check_database_version_supported()`函数
127 0
|
8天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
14天前
|
关系型数据库 MySQL 数据库连接
Django(四):Django项目部署数据库及服务器配置详解(MySQL)
Django(四):Django项目部署数据库及服务器配置详解(MySQL)
46 11
|
16天前
|
监控 数据可视化 安全
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
环境实时数据、动态监测报警,实时监控施工环境状态,有针对性地预防施工过程中的环境污染问题,打造文明生态施工,创造绿色的生态环境。
14 0
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
|
23天前
|
JavaScript Java 关系型数据库
基于 java + Springboot + vue +mysql 大学生实习管理系统(含源码)
本文档介绍了基于Springboot的实习管理系统的设计与实现。系统采用B/S架构,旨在解决实习管理中的人工管理问题,提高效率。系统特点包括对用户输入的验证和数据安全性保障。功能涵盖首页、个人中心、班级管理、学生管理、教师管理、实习单位管理、实习作业管理、教师评分管理、单位成绩管理和系统管理等。用户分为管理员、教师和学生,各自有不同的操作权限。
|
29天前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
380 1
|
1月前
|
NoSQL 关系型数据库 MySQL
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
221 0
|
1月前
|
NoSQL Java 应用服务中间件
使用innoSetup将mysql+nginx+redis+jar包打包成windows安装包
使用innoSetup将mysql+nginx+redis+jar包打包成windows安装包
使用innoSetup将mysql+nginx+redis+jar包打包成windows安装包
|
1月前
|
存储 关系型数据库 MySQL
手把手教你使用Django如何连接Mysql
手把手教你使用Django如何连接Mysql
81 0