Python二手商城交易系统

1:项目简介

今天分享一个二手交易平台的项目,也是PythonWeb的项目~

部分功能介绍如下: 项目功能简介:

- 商品浏览:商品的图片,售价,种类,简介以及库存等信息。

- 商品评论:用户在购买了商品后才会出现商品评论的文本框。

- 商品搜索:支持对商品种类以及商品的检索。

- 登录注册:用户的登录与注册,重置密码,密码发送到注册邮箱。

- 使用协议:协议签属才能使用。

- 用户中心:支持用户个人信息,收货地址,修改密码,发布商品,修改个人信息,实名认证,等信息的更新,商品加入购物车,订单生成。

- 消息中心:支持用户回复商家信息。

- 卖家中心:在商品详细信息中通过联系卖家进入。

- 商品下单:下单功能,按照原子事务处理,下单异常则终止此次下单过程。(真实的支付需要支付接口和企业资质的支持下才可以)

- 后台管理:支持后台管理功能,商品种类,商品及用户信息以及其他信息的增加,更新与删除。

2:项目核心代码

2.1: 数据库设计

2.1.1 用户数据表

from datetime import datetime

from django.db import models
from tinymce.models import HTMLField

from df_goods.models import GoodsInfo


# 01用户信息表
class UserInfo(models.Model):
    uname = models.CharField(max_length=20, verbose_name="用户名", unique=True)
    usex = models.CharField(max_length=10, verbose_name="性别", default="")
    uage = models.CharField(max_length=10, verbose_name="年龄", default="")
    upersonInf = models.CharField(max_length=200, verbose_name="个人简介", default="")
    ulogo = models.FileField(verbose_name="用户头像", upload_to='images', default='default.jpg')
    upwd = models.CharField(max_length=40, verbose_name="用户密码", blank=False)
    uemail = models.EmailField(verbose_name="邮箱", unique=True)
    urealname = models.CharField(max_length=20, default="", verbose_name="真实姓名")
    uzhengjian_type = models.CharField(max_length=20, default="", verbose_name="证件类型")
    uzhengjian_tel = models.CharField(max_length=18, default="", verbose_name="证件号码")
    uzhengjian_img = models.FileField(upload_to='images/zhengjian_img', default="", verbose_name="证件图片")
    ucheck_passOrfail = models.BooleanField(verbose_name="认证审批", default=False)
    ushou = models.CharField(max_length=20, default="", verbose_name="收货名称")
    uaddress = models.CharField(max_length=100, default="", verbose_name="地址")
    uyoubian = models.CharField(max_length=6, default="", verbose_name="邮编")
    uphone = models.CharField(max_length=11, default="", verbose_name="手机号")
    uname_passOrfail = models.BooleanField(verbose_name="允许登录", default=True)

    class Meta:
        verbose_name = "用户信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.uname


# 02浏览记录表
class GoodsBrowser(models.Model):
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE, verbose_name="用户ID")
    good = models.ForeignKey(GoodsInfo, on_delete=models.CASCADE, verbose_name="商品ID")
    browser_time = models.DateTimeField(default=datetime.now, verbose_name="浏览时间")

    class Meta:
        verbose_name = "用户浏览记录"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0}浏览记录{1}".format(self.user.uname, self.good.gtitle)


# 03联系卖家消息信息表
class Information(models.Model):
    isDelete = models.BooleanField(default=False)  # 逻辑删除
    ctitle = models.CharField(max_length=20, verbose_name="商品名称")
    cusername = models.CharField(max_length=20, verbose_name="买家昵称")
    cusername1 = models.CharField(max_length=20, verbose_name="卖家昵称")
    ccontent_chart = HTMLField(max_length=200, verbose_name="消息内容")
    ccheck = models.BooleanField(verbose_name="消息是否已读", default=False)
    date_publish = models.DateTimeField(verbose_name="发表时间", default=datetime.now)
    cinformation = models.ForeignKey(UserInfo, on_delete=models.CASCADE, verbose_name="消息")  # 外键关联GoodsContent表

    class Meta:
        verbose_name = "用户消息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.cusername1


# 04退货信息表
class tuihuoInfo(models.Model):
    isDelete = models.BooleanField(default=False)  # 逻辑删除
    title = models.CharField(max_length=20, verbose_name="商品名称")
    username = models.CharField(max_length=20, verbose_name="收件人姓名")
    username1 = models.CharField(max_length=20, verbose_name="寄件人姓名")
    person_number = models.CharField(max_length=20, verbose_name="身份证号码")
    order_number = models.CharField(max_length=20, verbose_name="订单号")
    kuaidi = models.CharField(max_length=20, verbose_name="快递类型")
    kuaidi_number = models.CharField(max_length=20, verbose_name="快递单号")
    address = models.CharField(max_length=50, verbose_name="收货地址", default=None)
    address1 = models.CharField(max_length=50, verbose_name="发货地址", default=None)
    text = HTMLField(max_length=200, verbose_name="退货理由", default=None)
    passOrdefault = models.BooleanField(verbose_name="同意退款", default=False)
    date_publish = models.DateTimeField(verbose_name="发表时间", default=datetime.now)

    class Meta:
        verbose_name = "退款订单信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

# python manage.py makemigrations
# python manage.py migrate

2.1.2  商品数据表

from datetime import datetime

from django.db import models
from tinymce.models import HTMLField  # 使用富文本编辑框要在settings文件中安装


# 商品分类信息
class TypeInfo(models.Model):
    isDelete = models.BooleanField(default=False)
    ttitle = models.CharField(max_length=20, verbose_name="分类")

    class Meta:
        verbose_name = "商品类型表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.ttitle


# 商品信息表
class GoodsInfo(models.Model):
    isDelete = models.BooleanField(default=False)
    gtitle = models.CharField(max_length=128, verbose_name="商品名称", unique=True)
    gpic = models.ImageField(verbose_name='商品图片', upload_to='df_goods/image/%Y/%m', null=True, blank=True)  # 商品图片
    gprice = models.DecimalField(max_digits=7, decimal_places=2, verbose_name="商品价格")  # 商品价格小数位为两位,整数位为3位
    gunit = models.CharField(max_length=20, verbose_name="卖家昵称")
    gclick = models.IntegerField(verbose_name="点击量", default=0, null=False)
    gjianjie = models.CharField(max_length=200, verbose_name="简介")
    gkucun = models.IntegerField(verbose_name="库存", default=0)
    gcontent = HTMLField(max_length=100000, verbose_name="详情")
    gtype = models.ForeignKey(TypeInfo, on_delete=models.CASCADE, verbose_name="分类")  # 外键关联TypeInfo表

    class Meta:
        verbose_name = "商品信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.gtitle


# 用户评论信息表
class GoodsContent(models.Model):
    isDelete = models.BooleanField(default=False)
    ctitle = models.CharField(max_length=20, verbose_name="商品名称")
    cpic = models.ImageField(verbose_name='上传图片', upload_to='df_goods/image/%Y/%m', null=True, blank=True)  # 商品图片
    cusername = models.CharField(max_length=20, verbose_name="买家昵称")
    clogo = models.CharField(verbose_name='买家头像', max_length=200, default=None)
    cuser_content = HTMLField(max_length=200, verbose_name="用户评论")
    date_publish = models.DateTimeField(verbose_name="发表时间", default=datetime.now)
    cgoodsname = models.ForeignKey(GoodsInfo, on_delete=models.CASCADE, verbose_name="外键商品")  # 外键关联GoodsInfo表

    class Meta:
        verbose_name = "商品评论"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.ctitle


# 评论回复信息表
class ContentChart(models.Model):
    isDelete = models.BooleanField(default=False)
    ctitle = models.CharField(max_length=20, verbose_name="商品名称")
    cusername = models.CharField(max_length=20, verbose_name="评论者昵称")
    cusername1 = models.CharField(max_length=20, verbose_name="回复者昵称")
    ccontent_chart = HTMLField(max_length=200, verbose_name="评论回复")
    date_publish = models.DateTimeField(verbose_name="发表时间", default=datetime.now)
    ccontent = models.ForeignKey(GoodsContent, on_delete=models.CASCADE, verbose_name="评论id")  # 外键关联GoodsContent表

    class Meta:
        verbose_name = "评论回复"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.ctitle

2.1.3 购物车表

from django.db import models

from df_user.models import UserInfo
from df_goods.models import GoodsInfo


# 购物车信息表
class CartInfo(models.Model):
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE, verbose_name="用户")
    goods = models.ForeignKey(GoodsInfo, on_delete=models.CASCADE, verbose_name="商品")
    count = models.IntegerField(verbose_name="", default=0)  # 记录用户买个多少单位的商品

    class Meta:
        verbose_name = "购物车信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.user.uname + '的购物车'

2.1.4 订单数据表

from django.db import models
from datetime import datetime

from df_goods.models import GoodsInfo
from df_user.models import UserInfo


# 订单状态信息表
class OrderInfo(models.Model):
    oid = models.CharField(max_length=20, primary_key=True, verbose_name="大订单号")
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE, verbose_name="订单用户")
    odate = models.DateTimeField(auto_now=True, verbose_name="时间")
    oIsPay = models.BooleanField(default=False, verbose_name="是否支付")
    ototal = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="总价")
    oaddress = models.CharField(max_length=150, verbose_name="订单地址")

    class Meta:
        verbose_name = "未付款订单"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0}在的订单{1}".format(self.user.uname, self.odate) 


# 订单详细信息表
class OrderDetailInfo(models.Model):
    goods = models.ForeignKey(GoodsInfo, on_delete=models.CASCADE, verbose_name="商品")
    username = models.CharField(max_length=20, verbose_name="买家昵称", default=None)
    shopername = models.CharField(max_length=20, verbose_name="卖家昵称", default="")
    datatime = models.DateTimeField(verbose_name="交易时间", default=datetime.now)
    order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name="订单")
    price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="商品价格")
    count = models.IntegerField(verbose_name="商品数")

    class Meta:
        verbose_name = "付款订单"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0}(数量为{1})".format(self.goods.gtitle, self.count)

2.2: 核心后台业务逻辑代码

2.2.1 用户数据表业务逻辑代码

from hashlib import sha1
from random import Random

from django.contrib import messages
from django.core.mail import send_mail
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render, redirect, HttpResponseRedirect, reverse

from df_cart.models import CartInfo
from df_goods.models import TypeInfo
from df_order.models import *
from . import user_decorator
from .models import GoodsBrowser, Information, tuihuoInfo


# 跳转到注册页面
def register(request):
    context = {
        'title': '用户注册',
    }
    return render(request, 'df_user/register.html', context)


# 注册处理
def register_handle(request):
    username = request.POST.get('user_name')
    password = request.POST.get('pwd')
    confirm_pwd = request.POST.get('confirm_pwd')
    email = request.POST.get('email')

    # 判断两次密码一致性
    if password != confirm_pwd:
        return redirect('/user/register/')
    # 密码加密
    s1 = sha1()
    s1.update(password.encode('utf8'))
    # 作为十六进制数据字符串值加密
    encrypted_pwd = s1.hexdigest()

    # 创建对象
    UserInfo.objects.create(uname=username, upwd=encrypted_pwd, uemail=email)
    # 注册成功
    context = {
        'title': '用户登陆',
        'username': username,
    }
    return render(request, 'df_user/login.html', context)


# 注册时判断用户是否已经存在
def register_exist(request):
    username = request.GET.get('uname')
    uemail = request.GET.get('uemail')
    count = UserInfo.objects.filter(uname=username).count()
    email_count = UserInfo.objects.filter(uemail=uemail).count()
    return JsonResponse({'count': count, 'email_count': email_count})


# 登录界面显示
def login(request):
    uname = request.COOKIES.get('uname', '')
    context = {
        'title': '用户登陆',
        'error_name': 0,
        'error_pwd': 0,
        'error_vc': 0,
        'uname': uname,
    }
    return render(request, 'df_user/login.html', context)


# 验证码显示
def verify_show(request):
    return render(request, 'df_user/login.html')


# 登录处理
def login_handle(request):
    # 接受请求信息
    uname = request.POST.get('username')
    upwd = request.POST.get('pwd')
    jizhu = request.POST.get('jizhu', 0)  # 记住密码
    vc = request.POST.get('vc')  # 输入的验证码
    verifycode = request.session['verifycode']
    user = UserInfo.objects.filter(uname=uname)
    if len(user) == 1:  # 判断用户密码并跳转
        s1 = sha1()
        s1.update(upwd.encode('utf8'))
        # 验证通过
        if s1.hexdigest() == user[0].upwd and vc == verifycode and user[0].uname_passOrfail is True:
            url = request.COOKIES.get('url', '/')  # 跳转首页
            red = HttpResponseRedirect(url)  # 继承与HttpResponse 在跳转的同时 设置一个cookie值
            # 是否勾选记住用户名,设置cookie
            if jizhu != 0:
                red.set_cookie('uname', uname)
            else:
                red.set_cookie('uname', '', max_age=-1)  # 设置过期cookie时间,立刻过期
            request.session['user_id'] = user[0].id
            request.session['user_name'] = uname
            return red
        # 验证码输入错误
        elif s1.hexdigest() == user[0].upwd and vc != verifycode:
            context = {
                'title': '用户名登陆',
                'error_name': 0,
                'error_pwd': 0,
                'error_vc': 1,
                'uname': uname,
                'upwd': upwd,
                'user': user,
                'vc': vc,
            }
            return render(request, 'df_user/login.html', context)

        # 账号不允许登录
        elif user[0].uname_passOrfail is False:
            messages.success(request, "你的账号存在违规行为,已被封禁!")
            context = {
                'title': '用户名登陆',
                'uname': uname,
                'upwd': upwd,
                'user': user,
                'vc': vc,
            }
            return render(request, 'df_user/login.html', context)
        # 账号密码输入有误
        else:
            context = {
                'title': '用户名登陆',
                'error_name': 0,
                'error_pwd': 1,
                'error_vc': 1,
                'uname': uname,
                'upwd': upwd,
                'user': user,
                'vc': vc,
            }
            return render(request, 'df_user/login.html', context)
    # 不存在该账户
    else:
        context = {
            'title': '用户名登陆',
            'error_name': 1,
            'error_pwd': 0,
            'error_vc': 0,
            'uname': uname,
            'upwd': upwd,
            'user': user,
            'vc': vc,
        }
        return render(request, 'df_user/login.html', context)


# 退出登录
def logout(request):  # 用户登出
    request.session.flush()  # 清空当前用户所有session
    return redirect(reverse("df_goods:index"))


# 忘记密码时,发送邮件生成的随机密码
def random_str(randomlength=8):  # 8位数
    str = ''
    chars = 'abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    length = len(chars) - 1
    random = Random()
    # 随机生成验证码
    for i in range(randomlength):
        str += chars[random.randint(0, length)]
    return str


# 发送邮件重置密码
def findpwdView(request):
    context = {
        'title': '重置密码',
    }
    if request.method == "POST":
        username = request.POST.get("username")
        email = request.POST.get("email")
        user = UserInfo.objects.get(uname=username)
        context = {
            'title': '重置密码',
            'user': user,
        }
        # 邮箱号验证
        if user.uemail == email:
            email_title = "Django二手商城系统-重置密码"
            code = random_str()  # 随机生成的验证码
            request.session["MarketSystem"] = code  # 将验证码保存到session
            email_body = "Django二手商城系统提醒您:您的密码已重置,为了您的账号安全,请勿将密码泄露!您的新的密码为:{0}".format(code)
            # send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们)
            send_status = send_mail(email_title, email_body, 'bhml2023@163.com', [email], fail_silently=False)
            code = request.session["MarketSystem"]  # 获取传递过来的验证码
            # 密码加密后存入数据库
            s1 = sha1()
            s1.update(code.encode('utf8'))
            encrypted_pwd = s1.hexdigest()
            user.upwd = encrypted_pwd
            user.save()
            del request.session["MarketSystem"]  # 删除session
            messages.success(request, "密码已重置,请登录邮箱查看重置后的密码!")
        else:
            messages.success(request, "用户邮箱与输入邮件不匹配,重置密码失败!")

        return render(request, "df_user/change_password1.html", context)
    return render(request, "df_user/change_password1.html", context)


# 用户中心,需要登录验证
@user_decorator.login
def info(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    browser_goods = GoodsBrowser.objects.filter(user=user).order_by("-browser_time")  # 浏览记录
    cart_num = CartInfo.objects.filter(user_id=int(uid)).count()  # 购物车数量
    goods_list = []
    if browser_goods:
        goods_list = [browser_good.good for browser_good in browser_goods]  # 从浏览商品记录中取出浏览商品
        explain = '最近浏览'
    else:
        explain = '无最近浏览'

    context = {
        'title': '用户中心',
        'page_name': 1,
        'guest_cart': 1,
        'cart_num': cart_num,
        'user_phone': user.uphone,
        'user_address': user.uaddress,
        'user_name': user.uname,
        'user': user,
        'ucheck_passOrfail': user.ucheck_passOrfail,
        'goods_list': goods_list,
        'explain': explain,
    }
    return render(request, 'df_user/user_center_info.html', context)


# 用户订单信息,需要登录验证
@user_decorator.login
def order(request, index):
    user_id = request.session['user_id']
    orders_list = OrderInfo.objects.filter(user_id=int(user_id)).order_by('-odate')  # 订单列表
    cart_num = CartInfo.objects.filter(user_id=int(user_id)).count()
    tuohuo_infos = tuihuoInfo.objects.filter()  # 退货信息
    paginator = Paginator(orders_list, 2)  # 分页显示
    page = paginator.page(int(index))
    user = UserInfo.objects.get(id=request.session['user_id'])
    context = {
        'paginator': paginator,
        'page': page,
        'title': "用户中心",
        'user': user,
        'page_name': 1,
        'guest_cart': 1,
        'cart_num': cart_num,
        'tuohuo_infos': tuohuo_infos,
    }
    return render(request, 'df_user/user_center_order.html', context)


# 用户信息修改
@user_decorator.login
def site(request):
    user = UserInfo.objects.get(id=request.session['user_id'])
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    if request.method == "POST":
        user.ushou = request.POST.get('ushou')
        user.uaddress = request.POST.get('uaddress')
        user.uyoubian = request.POST.get('uyoubian')
        user.uphone = request.POST.get('uphone')
        user.save()
    context = {
        'page_name': 1,
        'title': '用户中心',
        'user': user,
        'guest_cart': 1,
        'cart_num': cart_num,
    }
    return render(request, 'df_user/user_center_site.html', context)


# 发布商品,需要登录验证、实名验证
@user_decorator.login
def publishers(request):
    user = UserInfo.objects.get(id=request.session['user_id'])
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    typeinfos = TypeInfo.objects.all()
    # 实名认证验证
    if user.ucheck_passOrfail is False:
        messages.success(request, "请先进行实名认证!")
        context = {
            'page_name': 1,
            'title': '用户中心',
            'user': user,
            'typeinfos': typeinfos,
            'guest_cart': 1,
            'cart_num': cart_num,
        }
        return render(request, 'df_user/user_publishers.html', context)
    if request.method == "POST":
        gtitle = request.POST.get('title')  # 标题
        gpic = request.FILES.get('pic')  # 图片
        gunit = user.uname  # 卖家信息
        gprice = request.POST.get('price')  # 价格
        gjianjie = request.POST.get('jianjie')  # 商品简介
        gkucun = request.POST.get('kucun')  # 库存数量
        gcontent = request.POST.get('content')  # 商品内容介绍
        gtype_id = request.POST.get('type_id')  # 商品类型
        if gtitle == "" or gpic == "" or gprice == "" or gjianjie == "" or gkucun == "" or gcontent == "":
            messages.success(request, "请完整并正确填充信息!")
        elif float(gprice) >= 9999:
            messages.success(request, "价格不能大于9999元!")
        else:
            GoodsInfo.objects.create(gtitle=gtitle, gpic=gpic, gunit=gunit, gprice=gprice, gjianjie=gjianjie,
                                     gkucun=gkucun, gcontent=gcontent, gtype_id=gtype_id)
            messages.success(request, "发布商品成功")

    context = {
        'page_name': 1,
        'title': '用户中心',
        'user': user,
        'typeinfos': typeinfos,
        'guest_cart': 1,
        'cart_num': cart_num,
    }
    return render(request, 'df_user/user_publishers.html', context)


# 修改资料、头像,需要登录验证
@user_decorator.login
def changeInformation(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    context = {
        'page_name': 1,
        'title': '用户中心',
        'user': user,
        'guest_cart': 1,
        'cart_num': cart_num,
    }

    if request.method == "POST":
        logo = request.FILES.get('logo')
        if logo:
            user.ulogo = logo
        else:
            user.ulogo = user.ulogo
        user.usex = request.POST.get('sex')
        user.uage = request.POST.get('age')
        user.upersonInf = request.POST.get('personinf')
        user.save()
    return render(request, 'df_user/user_changeInformation.html', context)


# 修改密码,需要登录验证
@user_decorator.login
def changeInPwd(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    context = {
        'page_name': 1,
        'title': '用户中心',
        'user': user,
        'guest_cart': 1,
        'cart_num': cart_num,
    }

    if request.method == "POST":
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        if password == "" or password2 == "":
            messages.success(request, "请输入要修改的密码!")
        elif password == password2:
            # 密码加密
            s1 = sha1()
            s1.update(password.encode('utf8'))
            encrypted_pwd = s1.hexdigest()
            user.upwd = encrypted_pwd
            user.save()
            messages.success(request, "修改成功!")
        else:
            messages.success(request, "两次密码输入不正确!")
    return render(request, 'df_user/user_changePwd.html', context)


# 实名认证,需要登录验证
@user_decorator.login
def check_user(request):
    user = UserInfo.objects.get(id=request.session['user_id'])
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    if request.method == "POST":
        user.urealname = request.POST.get('name')  # 真实姓名
        user.uzhengjian_type = request.POST.get('type_id')  # 证件类型
        user.uzhengjian_tel = request.POST.get('tel')  # 证件号码
        user.uzhengjian_img = request.FILES.get('pic')  # 证件图片
        if user.urealname is None or user.uzhengjian_type is None or \
                user.uzhengjian_tel is None or user.uzhengjian_img is None:
            messages.success(request, "请填写完整的信息")
        else:
            user.save()
            messages.success(request, "提交成功,请等待管理员审批!")
    context = {
        'page_name': 1,
        'title': '用户中心',
        'user': user,
        'guest_cart': 1,
        'cart_num': cart_num,
    }
    return render(request, 'df_user/user_check_username.html', context)


# 卖家中心-查看卖家信息
def shoper_information(request, cname):
    shoper = UserInfo.objects.get(uname=cname)  # 卖家信息
    content_username = cname # 卖家信息
    # 列举卖家上架的商品
    goods = GoodsInfo.objects.filter(gunit=content_username)
    # 获取订单中的货物id,有多少该卖家的商品
    orderinfs = OrderDetailInfo.objects.filter(shopername=cname).order_by('-datatime')
    infors = GoodsInfo.objects.filter()
    # 创建Paginator一个分页对象
    # 发送信息
    if 'user_id' in request.session:
        uid = request.session['user_id']
        user = UserInfo.objects.get(id=uid)
        # 给卖家发消息
        if request.method == "POST":
            ctitle = request.POST.get('title')
            cusername = user.uname
            cusername1 = content_username
            ccontent_chart = request.POST.get('Message')
            cinformation_id = shoper.id
            if ctitle == "" or ccontent_chart == "":
                messages.success(request, "请把信息填完整,卖家能够够快回复你哦!")
            else:
                Information.objects.create(ctitle=ctitle, cusername=cusername, cusername1=cusername1,
                                           ccontent_chart=ccontent_chart, cinformation_id=cinformation_id)
                messages.success(request, "消息发送成功")
        context = {
            'goods': goods,
            'orderinfs': orderinfs,
            'name': content_username,
            'user': user,
            'shoper': shoper,
            'infos': infors,
        }
        return render(request, 'df_user/shoper_information.html', context)
    else:
        if request.method == "POST":
            return render(request, 'df_user/login.html')
    context = {
        'goods': goods,
        'orderinfs': orderinfs,
        'name': content_username,
        'shoper': shoper,
        'infos': infors,
    }
    return render(request, 'df_user/shoper_information.html', context)


# 卖家中心-查看自己作为卖家的卖家信息
def myself_information(request):
    if 'user_id' in request.session:
        uid = request.session['user_id']
        user = UserInfo.objects.get(id=uid)
        # 列举卖家上架的商品
        goods = GoodsInfo.objects.filter(gunit=user.uname)
        # 获取订单中的货物id,有多少该卖家的商品
        orderinfs = OrderDetailInfo.objects.filter(shopername=user.uname).order_by('-datatime')
        infors = GoodsInfo.objects.filter()

        context = {
            'goods': goods,
            'orderinfs': orderinfs,
            'user': user,
            'infors': infors,
        }
        return render(request, 'df_user/myself_information.html', context)


# 用户消息中心
@user_decorator.login
def message(request):
    user = UserInfo.objects.get(id=request.session['user_id'])
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    # 消息用户名去重
    persons = Information.objects.filter(cinformation_id=user.id).values('cusername', 'ccheck').distinct().\
        order_by('cusername')
    # 查询发消息者的头像
    imgs = UserInfo.objects.filter()
    context = {
        'title': '消息中心',
        'page_name': 1,
        'user': user,
        'persons': persons,
        'imgs': imgs,
        'guest_cart': 1,
        'cart_num': cart_num,
        'username': user.uname,
    }
    return render(request, 'df_user/user_messages.html', context)


# 消息内容展示
@user_decorator.login
def person_message(request):
    user = UserInfo.objects.get(id=request.session['user_id'])  # 当前登录用户
    cart_num = CartInfo.objects.filter(user_id=user.id).count()
    # 消息用户名去重
    persons = Information.objects.filter(cinformation_id=user.id).values('cusername', 'ccheck').distinct().\
        order_by('cusername')
    # 查询发消息者的头像
    imgs = UserInfo.objects.filter()
    # 展示消息
    username = request.GET['username']
    informations = Information.objects.filter()
    # print(type(informations[1].ctitle))
    # print(informations[1].ctitle=="")
    logo = UserInfo.objects.get(uname=username)
    # 展示消息后使消息变为已读状态
    for information in informations:
        if information.cusername == username:
            information.ccheck = True
            information.save()
    # 消息回复
    user_name = UserInfo.objects.get(uname=username)  # 获取当前消息用户信息
    # 展示回复消息
    if request.method == "POST":
        cusername = user.uname
        cusername1 = user_name.uname
        ccontent_chart = request.POST.get('title')
        cinformation_id = user_name.id
        if ccontent_chart == "":
            messages.success(request, "请输入内容!")
        else:
            Information.objects.create(cusername=cusername, cusername1=cusername1,
                                       ccontent_chart=ccontent_chart, cinformation_id=cinformation_id)
            messages.success(request, "消息发送成功")
            return redirect(reverse("df_user:message"))
    context = {
        'title': '消息中心',
        'page_name': 1,
        'user': user,
        'informations': informations,
        'persons': persons,
        'imgs': imgs,
        'logo': logo,
        'username': username,
        'user_name': user_name,
        'guest_cart': 1,
        'cart_num': cart_num,
    }
    # print(user.ulogo)
    # print(logo.ulogo)
    return render(request, 'df_user/user_messages.html', context)


# 退货处理
@user_decorator.login
def tuihuo(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    if request.method == "POST":
        title = request.POST.get('title')
        username = request.POST.get('username')
        username1 = request.POST.get('username1')
        person_number = request.POST.get('person_number')
        order_number = request.POST.get('order_number')
        kuaidi = request.POST.get('kuaidi')
        kuaidi_number = request.POST.get('kuaidi_number')
        address = request.POST.get('address')
        address1 = request.POST.get('address1')
        text = request.POST.get('text')
        if title == "" or username == "" or username1 == "" or person_number == "" or order_number == "" or kuaidi == "" or kuaidi_number == "" or address == "" or address1 == "":
            messages.success(request, "请填写完整信息!")
        else:
            tuihuoInfo.objects.create(title=title, username=username, username1=username1, person_number=person_number,
                                      order_number=order_number, kuaidi=kuaidi, kuaidi_number=kuaidi_number,
                                      address=address, address1=address1, text=text)
            messages.success(request, "提交成功,请等待审批!")
            return redirect(reverse("df_user:info"))

    context = {
        'title': '填写退货信息',
        'page_name': 1,
        'user': user,
    }
    return render(request, 'df_user/tuihuo.html', context)

2.2.2 商品数据表后台业务处理

from django.contrib import messages
from django.core.paginator import Paginator
from django.shortcuts import render, redirect
from django.urls import reverse

from df_cart.models import CartInfo
from df_order.models import OrderDetailInfo
from df_user import user_decorator
from df_user.models import GoodsBrowser
from df_user.models import UserInfo, Information
from .models import GoodsInfo, TypeInfo, GoodsContent


# 01首页数据
def index(request):
    # 查询各个分类的最新4条,最热4条数据
    username = request.session.get('user_name')
    print(username)
    user = UserInfo.objects.filter(uname=username).first()
    print(user)
    import datetime
    nowTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 现在
    informations = Information.objects.filter()
    if user is not None:
        # 联系客服
        # 展示消息
        username1 = user.uname
        # print(informations)
        # 判断用户是否给客服发过信息
        informations1 = Information.objects.filter(cusername1=username, cusername=username1)
        # print(informations1)
        # 消息回复
        user_name = UserInfo.objects.get(uname=username1)  # 获取当前消息用户信息
        print(user_name)
    else:
        informations1 = None
        username1 = None
        user_name = None
    # 展示回复消息
    # persons1=Information.objects.filter(cusername=cusername).values('cusername1').distinct().order_by('cusername1')
    if request.method == "POST":
        cusername = user.uname
        cusername1 = user_name.uname
        ccontent_chart = request.POST.get('title')
        cinformation_id = user_name.id
        if ccontent_chart == "":
            messages.success(request, "请输入内容!")
        else:
            Information.objects.create(cusername=cusername, cusername1=cusername1,
                                       ccontent_chart=ccontent_chart, cinformation_id=cinformation_id)
            messages.success(request, "消息发送成功")
            return redirect(reverse("df_goods:index"))
    typelist = TypeInfo.objects.all()

    if len(typelist[0].goodsinfo_set.order_by('-id')) <= 4:
        type0 = typelist[0].goodsinfo_set.order_by('-id')  # 按照上传顺序
        type01 = typelist[0].goodsinfo_set.order_by('-gclick')  # 按照点击量
    else:
        type0 = typelist[0].goodsinfo_set.order_by('-id')[0:4]
        type01 = typelist[0].goodsinfo_set.order_by('-gclick')[0:4]

    if len(typelist[1].goodsinfo_set.order_by('-id')) <= 4:
        type1 = typelist[1].goodsinfo_set.order_by('-id')
        type11 = typelist[1].goodsinfo_set.order_by('-gclick')
    else:
        type1 = typelist[1].goodsinfo_set.order_by('-id')[0:4]
        type11 = typelist[1].goodsinfo_set.order_by('-gclick')[0:4]

    if len(typelist[2].goodsinfo_set.order_by('-id')) <= 4:
        type2 = typelist[2].goodsinfo_set.order_by('-id')
        type21 = typelist[2].goodsinfo_set.order_by('-gclick')
    else:
        type2 = typelist[2].goodsinfo_set.order_by('-id')[0:4]
        type21 = typelist[2].goodsinfo_set.order_by('-gclick')[0:4]

    if len(typelist[3].goodsinfo_set.order_by('-id')) <= 4:
        type3 = typelist[3].goodsinfo_set.order_by('-id')
        type31 = typelist[3].goodsinfo_set.order_by('-gclick')
    else:
        type3 = typelist[3].goodsinfo_set.order_by('-id')[0:4]
        type31 = typelist[3].goodsinfo_set.order_by('-gclick')[0:4]

    if len(typelist[4].goodsinfo_set.order_by('-id')) <= 4:
        type4 = typelist[4].goodsinfo_set.order_by('-id')
        type41 = typelist[4].goodsinfo_set.order_by('-gclick')
    else:
        type4 = typelist[4].goodsinfo_set.order_by('-id')[0:4]
        type41 = typelist[4].goodsinfo_set.order_by('-gclick')[0:4]

    if len(typelist[5].goodsinfo_set.order_by('-id')) <= 4:
        type5 = typelist[5].goodsinfo_set.order_by('-id')
        type51 = typelist[5].goodsinfo_set.order_by('-gclick')
    else:
        type5 = typelist[5].goodsinfo_set.order_by('-id')[0:4]
        type51 = typelist[5].goodsinfo_set.order_by('-gclick')[0:4]

    cart_num = 0
    # 判断是否存在登录状态
    # if request.session.has_key('user_id'):
    if 'user_id' in request.session:
        user_id = request.session['user_id']
        cart_num = CartInfo.objects.filter(user_id=int(user_id)).count()

    context = {
        'title': '首页',
        'cart_num': cart_num,
        'guest_cart': 1,
        'type0': type0, 'type01': type01,
        'type1': type1, 'type11': type11,
        'type2': type2, 'type21': type21,
        'type3': type3, 'type31': type31,
        'type4': type4, 'type41': type41,
        'type5': type5, 'type51': type51,
        'user': user,
        'informations': informations,
        'informations1': informations1,
        'username1': username1,
        'user_name': user_name,
        # 'nowTime': nowTime,
    }

    return render(request, 'df_goods/index.html', context)


# 02获取商品列表
def good_list(request, tid, pindex, sort):
    username = request.session.get('user_name')
    user = UserInfo.objects.filter(uname=username).first()
    # tid:商品种类信息  pindex:商品页码 sort:商品显示分类方式
    typeinfo = TypeInfo.objects.get(pk=int(tid))

    # 根据主键查找当前的商品分类
    news = typeinfo.goodsinfo_set.order_by('-id')[0:2]
    # list.html左侧最新商品推荐
    goods_list = []
    # list中间栏商品显示方式
    cart_num, guest_cart = 0, 0

    try:
        user_id = request.session['user_id']
    except:
        user_id = None
    if user_id:
        guest_cart = 1
        cart_num = CartInfo.objects.filter(user_id=int(user_id)).count()

    if sort == '1':  # 默认最新
        goods_list = GoodsInfo.objects.filter(gtype_id=int(tid)).order_by('-id')
    elif sort == '2':  # 按照价格
        goods_list = GoodsInfo.objects.filter(gtype_id=int(tid)).order_by('-gprice')
    elif sort == '3':  # 按照人气点击量
        goods_list = GoodsInfo.objects.filter(gtype_id=int(tid)).order_by('-gclick')

    # 创建Paginator一个分页对象
    paginator = Paginator(goods_list, 4)
    # 返回Page对象,包含商品信息
    page = paginator.page(int(pindex))
    context = {
        'title': '商品列表',
        'guest_cart': guest_cart,
        'cart_num': cart_num,
        'page': page,
        'paginator': paginator,
        'typeinfo': typeinfo,
        'sort': sort,  # 排序方式
        'news': news,
        'user': user,
    }
    return render(request, 'df_goods/list.html', context)

# 03查看商品详情
def detail(request, gid):
    if 'user_id' in request.session:
        uid = request.session['user_id']
        user = UserInfo.objects.get(id=uid)
        good_id = gid
        goods = GoodsInfo.objects.get(pk=int(good_id))
        goods.gclick = goods.gclick + 1  # 商品点击量
        goods.save()

        news = goods.gtype.goodsinfo_set.order_by('-id')[0:2]
        context = {
            'title': goods.gtype.ttitle,
            'guest_cart': 1,
            'cart_num': cart_count(request),
            'goods': goods,
            'news': news,
            'id': good_id,
            'user': user,
        }
        response = render(request, 'df_goods/detail.html', context)

        try:
            browsed_good = GoodsBrowser.objects.get(user_id=int(uid), good_id=int(good_id))
        except Exception:
            browsed_good = None
        if browsed_good:
            from datetime import datetime
            browsed_good.browser_time = datetime.now()
            browsed_good.save()
        else:
            GoodsBrowser.objects.create(user_id=int(uid), good_id=int(good_id))
            browsed_goods = GoodsBrowser.objects.filter(user_id=int(uid))
            browsed_good_count = browsed_goods.count()
            if browsed_good_count > 5:
                ordered_goods = browsed_goods.order_by("-browser_time")
                for _ in ordered_goods[5:]:
                    _.delete()
        return response

    else:
        good_id = gid
        goods = GoodsInfo.objects.get(pk=int(good_id))
        news = goods.gtype.goodsinfo_set.order_by('-id')[0:2]
        context = {
            'title': goods.gtype.ttitle,
            'guest_cart': 0,
            'cart_num': cart_count(request),
            'goods': goods,
            'news': news,
            'id': good_id,
        }
        return render(request, 'df_goods/detail.html', context)


# 04评论商品
def content(request, gid, pindex):
    if 'user_id' in request.session:
        uid = request.session['user_id']
        user = UserInfo.objects.get(id=uid)
        good_id = gid
        goods = GoodsInfo.objects.get(pk=int(good_id))
        # 获取当前货物信息
        news = goods.gtype.goodsinfo_set.order_by('-id')[0:2]
        # 条件查询
        goodsContents = GoodsContent.objects.filter(cgoodsname_id=good_id).order_by('-date_publish')

        # 订单信息
        goodsOrderDetailInfos = OrderDetailInfo.objects.filter()

        # 创建Paginator一个分页对象
        paginator = Paginator(goodsContents, 2)
        # 返回Page对象,包含商品信息
        page = paginator.page(int(pindex))
        for goodsContent in page:
            if goodsContent.cgoodsname_id == goods.id:
                content_id = goodsContent.id

        context = {
            'title': goods.gtype.ttitle,
            'guest_cart': 1,
            'cart_num': cart_count(request),
            'goods': goods,
            'id': good_id,
            'news': news,
            'user': user,
            'goodsContents': goodsContents,
            'paginator': paginator,
            'page': page,
            'goodsOrderDetailInfos': goodsOrderDetailInfos,
            # 'xinxi':xinxi,
        }
        if request.method == "POST":
            ctitle = goods.gtitle
            cpic = request.FILES.get('pic')
            cusername = user.uname
            clogo = user.ulogo
            cuser_content = request.POST.get('text')
            cgoodsname_id = goods.id
            if cpic == "":
                GoodsContent.objects.create(ctitle=ctitle, cusername=cusername, cuser_content=cuser_content,
                                            cgoodsname_id=cgoodsname_id, clogo=clogo)
                messages.success(request, "评论成功!")
            else:
                GoodsContent.objects.create(ctitle=ctitle, cpic=cpic, cusername=cusername, cuser_content=cuser_content,
                                            cgoodsname_id=cgoodsname_id, clogo=clogo)
                messages.success(request, "评论成功!")

        return render(request, 'df_goods/content.html', context)
    else:
        good_id = gid
        goods = GoodsInfo.objects.get(pk=int(good_id))
        # 获取当前货物信息
        news = goods.gtype.goodsinfo_set.order_by('-id')[0:2]
        # 条件查询
        goodsContents = GoodsContent.objects.filter(cgoodsname_id=good_id).order_by('-date_publish')

        print("当前商品评论数:")
        print(goodsContents.count())
        # 订单信息
        goodsOrderDetailInfos = OrderDetailInfo.objects.filter()

        # 创建Paginator一个分页对象
        paginator = Paginator(goodsContents, 2)
        # 返回Page对象,包含商品信息
        page = paginator.page(int(pindex))
        for goodsContent in page:
            if goodsContent.cgoodsname_id == goods.id:
                content_id = goodsContent.id

        context = {
            'title': goods.gtype.ttitle,
            'guest_cart': 0,
            'cart_num': cart_count(request),
            'goods': goods,
            'id': good_id,
            'news': news,
            'goodsContents': goodsContents,
            'paginator': paginator,
            'page': page,
            'goodsOrderDetailInfos': goodsOrderDetailInfos,
            # 'xinxi':xinxi,
        }
        return render(request, 'df_goods/content.html', context)


# 05获取购物车数量
@user_decorator.login
def cart_count(request):
    if 'user_id' in request.session:
        return CartInfo.objects.filter(user_id=request.session['user_id']).count
    else:
        return 0


# 06搜索商品
def ordinary_search(request):
    username = request.session.get('user_name')
    user = UserInfo.objects.filter(uname=username).first()
    from django.db.models import Q

    search_keywords = request.GET.get('q', '')
    pindex = request.GET.get('pindex', 1)
    search_status = 1
    cart_num, guest_cart = 0, 0

    try:
        user_id = request.session['user_id']
    except:
        user_id = None

    if user_id:
        guest_cart = 1
        cart_num = CartInfo.objects.filter(user_id=int(user_id)).count()

    goods_list = GoodsInfo.objects.filter(
        Q(gtitle__icontains=search_keywords) |
        Q(gcontent__icontains=search_keywords) |
        Q(gjianjie__icontains=search_keywords)).order_by("gclick")

    if goods_list.count() == 0:
        # 商品搜索结果为空,返回推荐商品
        search_status = 0
        goods_list = GoodsInfo.objects.all().order_by("gclick")[:4]

    paginator = Paginator(goods_list, 4)
    page = paginator.page(int(pindex))

    context = {
        'title': '搜索列表',
        'search_status': search_status,
        'guest_cart': guest_cart,
        'cart_num': cart_num,
        'page': page,
        'paginator': paginator,
        'user': user,
    }
    return render(request, 'df_goods/ordinary_search.html', context)


# 06查看更多
def show_more(request, type_):
    username = request.session.get('user_name')
    user = UserInfo.objects.filter(uname=username).first()
    type_title = ['图书', '电器', '衣物', '出行', '乐器', '数码']
    type = type_title[int(type_)]
    pindex = request.GET.get('pindex', 1)
    search_status = 1
    cart_num, guest_cart = 0, 0
    try:
        user_id = request.session['user_id']
    except:
        user_id = None

    if user_id:
        guest_cart = 1
        cart_num = CartInfo.objects.filter(user_id=int(user_id)).count()

    type = TypeInfo.objects.filter(ttitle=type).first()
    if type is None:
        goods_list = None
    else:
        goods_list = GoodsInfo.objects.filter(gtype_id=type.id).order_by("gclick")

    if goods_list is None or goods_list.count() == 0:
        # 商品搜索结果为空,返回推荐商品
        search_status = 0
        goods_list = GoodsInfo.objects.all().order_by("gclick")[:4]

    paginator = Paginator(goods_list, 4)
    page = paginator.page(int(pindex))

    context = {
        'title': '搜索列表',
        'search_status': search_status,
        'guest_cart': guest_cart,
        'cart_num': cart_num,
        'page': page,
        'paginator': paginator,
        'user': user,
    }
    return render(request, 'df_goods/ordinary_search.html', context)

2.2.3 购物车业务处理代码

from django.http import JsonResponse
from django.shortcuts import render, redirect, reverse

from .models import *
from df_user import user_decorator


# 查看购物车信息
@user_decorator.login
def user_cart(request):
    uid = request.session['user_id']
    username = request.session.get('user_name')
    user = UserInfo.objects.filter(uname=username).first()
    carts = CartInfo.objects.filter(user_id=uid)
    cart_num = CartInfo.objects.filter(user_id=uid).count()
    context = {
        'title': '购物车',
        'page_name': 1,
        'guest_cart': 1,
        'carts': carts,
        'cart_num': cart_num,
        'user': user,
    }
    if request.is_ajax():
        count = CartInfo.objects.filter(user_id=request.session['user_id']).count()
        # 求当前用户购买了几件商品
        return JsonResponse({'count': count})
    else:
        return render(request, 'df_cart/cart.html', context)


# 添加购物车
@user_decorator.login
def add(request, gid, count):
    uid = request.session['user_id']
    gid, count = int(gid), int(count)
    # 查询购物车中是否已经有此商品,如果有则数量增加,如果没有则新增
    carts = CartInfo.objects.filter(user_id=uid, goods_id=gid)
    if len(carts) >= 1:
        cart = carts[0]
        cart.count = cart.count + count
    else:
        cart = CartInfo()
        cart.user_id = uid
        cart.goods_id = gid
        cart.count = count
    cart.save()
    # 如果是ajax提交则直接返回json,否则转向购物车
    if request.is_ajax():
        count = CartInfo.objects.filter(user_id=request.session['user_id']).count()
        # 求当前用户购买了几件商品
        return JsonResponse({'count': count})
    else:
        return redirect(reverse("df_cart:cart"))


# 编辑购物车
@user_decorator.login
def edit(request, cart_id, count):
    data = {}
    try:
        cart = CartInfo.objects.get(pk=int(cart_id))
        cart.count = int(count)
        cart.save()
        data['count'] = 0
    except Exception as e:
        print(e)
        data['count'] = count
    return JsonResponse(data)


# 删除购物车
@user_decorator.login
def delete(request, cart_id):
    data = {}
    try:
        cart = CartInfo.objects.get(pk=int(cart_id))
        cart.delete()
        data['ok'] = 1
    except Exception as e:
        print(e)
        data['ok'] = 0
    return JsonResponse(data)

2.2.4 订单业务处理代码

from django.db import transaction
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse

from datetime import datetime
from decimal import Decimal

from .models import OrderInfo, OrderDetailInfo
from df_cart.models import CartInfo
from df_user.models import UserInfo
from df_user import user_decorator


# 查看订单
@user_decorator.login
def order(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    cart_ids = request.GET.getlist('cart_id')
    carts = []
    total_price = 0
    for goods_id in cart_ids:
        cart = CartInfo.objects.get(id=goods_id)
        carts.append(cart)
        total_price = total_price + float(cart.count) * float(cart.goods.gprice)

    total_price = float('%0.2f' % total_price)
    trans_cost = 5  # 默认运费设置
    total_trans_price = trans_cost + total_price
    context = {
        'title': '提交订单',
        'page_name': 1,
        'user': user,
        'carts': carts,
        'total_price': float('%0.2f' % total_price),
        'trans_cost': trans_cost,
        'total_trans_price': total_trans_price,
    }
    return render(request, 'df_order/place_order.html', context)


'''
提交订单必须是一个连续的过程,所以需要用到事务
事务提交:
这些步骤中,任何一环节一旦出错则全部退回
1. 创建订单对象
2. 判断商品库存是否充足
3. 创建 订单 详情 ,多个
4,修改商品库存
5. 删除购物车
'''

# 生成订单
@user_decorator.login
@transaction.atomic()  # 事务
def order_handle(request):
    uid = request.session['user_id']
    user = UserInfo.objects.get(id=uid)
    tran_id = transaction.savepoint()  # 保存事务发生点
    cart_ids = request.POST.get('cart_ids')  # 用户提交的订单购物车,此时cart_ids为字符串,例如'1,2,3,'
    user_id = request.session['user_id']  # 获取当前用户的id
    data = {}
    try:
        order_info = OrderInfo()  # 创建一个订单对象
        now = datetime.now()
        order_info.oid = '%s%d' % (now.strftime('%Y%m%d%H%M%S'), user_id)  # 订单号为订单提交时间和用户id的拼接
        order_info.odate = now  # 订单时间
        order_info.user_id = int(user_id)  # 订单的用户id
        order_info.ototal = Decimal(request.POST.get('total'))  # 从前端获取的订单总价
        order_info.oaddress = user.uaddress  # 从用户信息中获取收获地址
        order_info.save()  # 保存订单

        for cart_id in cart_ids.split(','):  # 逐个对用户提交订单中的每类商品即每一个小购物车
            cart = CartInfo.objects.get(pk=cart_id)  # 从CartInfo表中获取购物车对象
            order_detail = OrderDetailInfo()  # 订单中的每一个小商品订单
            order_detail.order = order_info  # 外键关联,小订单与大订单绑定
            goods = cart.goods  # 具体商品
            if cart.count <= goods.gkucun:  # 判断库存是否满足订单,如果满足,修改数据库
                goods.gkucun = goods.gkucun - cart.count
                goods.save()
                order_detail.goods = goods
                order_detail.price = goods.gprice
                order_detail.count = cart.count
                order_detail.username = user.uname
                order_detail.shopername = goods.gunit
                order_detail.save()
                cart.delete()  # 并删除当前购物车
            else:  # 否则,则事务回滚,订单取消
                transaction.savepoint_rollback(tran_id)
                return HttpResponse('库存不足')
        data['ok'] = 1
        transaction.savepoint_commit(tran_id)
    except Exception as e:
        print("%s" % e)
        print('未完成订单提交')
        transaction.savepoint_rollback(tran_id)  # 事务任何一个环节出错,则事务全部取消
    return JsonResponse(data)


# 支付
@user_decorator.login
def pay(request):
    pass

2.3: 项目路由显示

2.3.1 用户路由

from django.conf.urls import url, re_path
from django.views.static import serve

from MarketSystem import settings
from . import viewsUtil
from .views import *

app_name = 'df_user'

# 用户模块子路由
urlpatterns = [
    url(r'^register/$', register, name="register"),  # 注册
    url(r'^register_handle/$', register_handle, name="register_handle"),  # 注册处理
    url(r'^register_exist/$', register_exist, name="register_exist"),  # 退出注册
    url(r'^login/$', login, name="login"),  # 登录
    url(r'^login_handle/$', login_handle, name="login_handle"),  # 登录注册
    url(r'^info/$', info, name="info"),  # 用户中心
    url(r'^order/(\d+)$', order, name="order"),  # 订单信息
    url(r'^site/$', site, name="site"),  # 用户信息修改
    url(r'^publishers/$', publishers, name="publishers"),  # 发布商品
    url(r'^changeInformation/$', changeInformation, name="changeInformation"),  # 修改资料、头像
    url(r'^check_user/$', check_user, name="check_user"),  # 实名认证
    url('^myself_information/$', myself_information, name="myself_information"),  # 卖家中心-查看自己作为卖家的卖家信息
    url('^shoper_information/(.+)/$', shoper_information, name="shoper_information"),  # 卖家中心-查看卖家信息
    url('^message/$', message, name="message"),  # 用户消息中心
    url('^person_message/$', person_message, name="person_message"),  # 消息内容展示
    url(r'^logout/$', logout, name="logout"),  # 退出登录
    # 显示验证码
    url(r'^verify_show/$', verify_show, name="verify_show"),  # 验证码显示
    url(r'^verifycode/$', viewsUtil.verify_code, name="verifycode"),  # 生成验证码图片
    # 修改密码
    url(r'^changeInPwd/$', changeInPwd, name="changeInPwd"),  # 修改密码
    # 重置密码
    url(r'^findpwdView/$', findpwdView, name="findpwdView"),  # 发送邮件重置密码
    # 退货
    url(r'^tuihuo/$', tuihuo, name="tuihuo"),  # 退货处理
    re_path('^media/(?P<path>.*)/$', serve, {'document_root': settings.MEDIA_ROOT}),  # 文件上传路径配置
]

2.3.2 商品路由

from django.conf.urls import url, re_path
from django.views.static import serve

from MarketSystem import settings
from . import views

app_name = 'df_goods'

# 商品子路由
urlpatterns = [
    url('^$', views.index, name="index"),  # 首页
    url('^index/$', views.index, name="index"),  # 首页
    url('^list(\d+)_(\d+)_(\d+)/$', views.good_list, name="good_list"),  # 商品列表
    url('^detail/(\d+)/$', views.detail, name="detail"),  # 商品详情
    url('^content/(\d+)/(\d+)/$', views.content, name="content"),  # 商品评论
    url(r'^search/', views.ordinary_search, name="ordinary_search"),  # 搜索商品
    url(r'^show_more/(\d+)/$', views.show_more, name="show_more"),  # 查看更多
    re_path('^media/(?P<path>.*)/$', serve, {'document_root': settings.MEDIA_ROOT}),
]

2.3.3 购物车路由

from django.conf.urls import url

from . import views

app_name = 'df_cart'

# 购物车子路由
urlpatterns = [
    url(r'^$', views.user_cart, name="cart"),  # 查看购物车
    url(r'^add(\d+)_(\d+)/$', views.add, name="add"),  # 添加购物车
    url(r'^edit(\d+)_(\d+)/$', views.edit, name="edit"),  # 编辑购物车
    url(r'^delete(\d+)/$', views.delete, name="delete"),  # 删除购物车
]

2.3.4 订单路由

from django.conf.urls import url
from . import views

app_name = 'df_order'

# 订单子路由
urlpatterns = [
    url(r'^$', views.order, name="order"),  # 订单信息
    url(r'^push/$', views.order_handle, name="push"),  # 订单处理
]

3: 项目截图展示

4: 结语

该项目适合用于普通高校的本科课程设计和毕业设计,项目整体不错,项目工作量中等偏上,有很大的学习和参考意义!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊Coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值