Django搭建的完整电商网站源码:含用户系统、购物车、订单流程与支付宝沙箱支付
2026/6/9 14:39:25 网站建设 项目流程

本文还有配套的精品资源,点击获取

简介:这个Django电商项目开箱即用,基于Python 3.x和MySQL开发,已打通用户注册登录(支持邮箱激活)、地址管理、商品分类浏览、搜索与详情展示、新品推荐、购物车增删改查、下单流程、订单状态跟踪等核心环节。支付宝对接采用官方沙箱环境,支付跳转与回调逻辑完整可用。前端使用原生HTML/CSS/JS模板,无额外框架依赖;后端通过Django ORM操作数据库,附带dailyfresh.sql建表语句及初始化数据。部署方面提供uwsgi双实例配置(uwsgi.ini和uwsgi2.ini)、日志设置、pid文件管理,并包含首页轮播图、商品多维度排序(默认/价格/人气)、分页列表、用户浏览记录等细节功能。配套两份详细文档(项目说明文档.docx、python电商项目.docx)和页面功能说明文本,另有README.md和光影程序文档说明.txt辅助理解。所有页面如register.html、login.html、cart.html、place_order.html、user_center_info.html等均已实现并本地测试通过,适合课程设计、毕业设计或Django实战入门直接部署演示。

1. 项目概述:这不是一个“玩具项目”,而是一套可交付的电商最小可行系统

你手头拿到的这个Django电商源码包,不是网上常见的那种只有首页和商品列表的“半成品Demo”,也不是只跑通了登录注册就戛然而止的教学示例。它是一个真实业务逻辑闭环完整、部署路径清晰、细节打磨到位的最小可行电商系统(MVP)。我带过十几届学生做毕设,也帮三四家公司做过内部培训系统,见过太多所谓“完整电商”项目——点开一看,购物车加不进去,订单状态永远卡在“待支付”,支付宝回调地址404,或者连用户邮箱激活链接都拼错了。而这个项目,从register.html点击注册,到收到邮箱里的激活邮件,再到点击链接完成激活、登录、浏览商品、加入购物车、填写收货地址、提交订单、跳转支付宝沙箱、模拟付款、回到网站看到订单状态自动变成“已支付”,整个链路是一气呵成、无断点、无报错的。它解决的不是一个技术点,而是“如何让一个电商网站真正跑起来”这个根本问题。

核心关键词“Django电商、支付宝沙箱、购物车系统、订单管理、用户中心”,每一个都不是虚词,而是对应着一套经过本地反复验证的、有血有肉的实现。比如“支付宝沙箱”,它不是简单贴了个SDK文档链接,而是把alipay_sdk_python的调用封装进了apps/order/views.pyOrderPlaceViewOrderCommitView里,回调接口/order/checkpay/直接对接支付宝官方沙箱的异步通知地址,连验签逻辑都写在了utils/alipay.py里,用的是官方推荐的RSA2签名方式;再比如“购物车系统”,它没用Redis搞复杂缓存,而是基于Django Session实现了轻量级、够用且安全的购物车存储,所有增删改查操作都通过apps/cart/views.py里的CartAddViewCartUpdateViewCartDeleteView统一处理,连前端JS调用的API路径、参数格式、返回结构都在cart.js里写得明明白白。它不追求炫技,但每一步都踩在Django最佳实践的节奏上:模型设计遵循单一职责(User,Address,GoodsSKU,OrderInfo,OrderGoods各司其职),视图逻辑清晰分离(FBV处理简单逻辑,CBV处理复杂流程),模板继承体系严谨(base.html定义骨架,common_head.htmlcommon_footer.html复用头部尾部),静态文件管理规范(static/css/,static/js/,static/images/目录分明)。它适合谁?如果你是计算机专业大三学生,正在为毕设发愁,这个项目能让你在两周内完成部署、演示、答辩;如果你是刚学完Django ORM和视图基础的自学者,它就是一本活的《Django实战手册》,每个.py文件、每个.html模板都是可运行的代码注释;如果你是小团队的技术负责人,想快速搭建一个内部商城原型,它提供的uwsgi双实例配置、MySQL建表语句、日志轮转方案,都是可以直接抄作业的生产级参考。它不承诺“一键上线”,但它承诺“你照着README.md和两份Word文档,一定能跑起来”。

2. 整体架构与设计思路:为什么选择这套组合拳?

2.1 技术栈选型:务实主义者的最优解

这个项目的整体技术栈,是典型的“够用、稳定、易上手”路线,没有为了时髦而堆砌新技术,每一个选择背后都有明确的业务约束和工程考量。

  • 后端框架:Django 2.2 LTS(长期支持版)
    为什么不是更新的Django 4.x或5.x?因为这是一个面向教学和毕设的项目,稳定性压倒一切。Django 2.2是官方提供长达三年安全更新的LTS版本,社区生态成熟,教程资料海量,遇到问题几乎都能在Stack Overflow上找到答案。更重要的是,它的中间件机制、ORM语法、URL路由规则,与当前主流企业应用的Django实践高度一致,学了不会“学完即废”。它内置的Admin后台、认证系统(django.contrib.auth)、表单验证(forms.py)等模块,被项目充分利用,比如用户注册激活流程,就是基于Django自带的UserCreationFormsend_mail函数二次开发的,而不是自己从零造轮子。

  • 数据库:MySQL 5.7+
    选择MySQL而非SQLite或PostgreSQL,是出于真实业务场景的模拟。电商系统对事务一致性、并发读写能力要求高,MySQL的InnoDB引擎完美支持ACID事务,OrderInfoOrderGoods两张表之间的外键约束、SELECT ... FOR UPDATE锁行操作,都是保障订单数据不重复、不丢失的关键。附带的dailyfresh.sql文件,不仅包含了建表语句,还预置了goods_type(商品分类)、goods_sku(具体商品)、goods_image(商品图片)等关联表结构,并填充了测试数据(如“牛奶”、“面包”、“水果”等分类下的几十个SKU),让你导入后就能立刻看到一个有内容的首页,而不是面对一片空白的后台。

  • 前端:原生HTML/CSS/JS + Bootstrap 3.3.7
    没有用Vue或React,是因为这个项目的核心目标是“理解电商逻辑”,而非“学习前端框架”。Bootstrap 3.3.7是一个足够成熟、文档齐全、组件丰富的CSS框架,list.html里的商品网格布局、detail.html里的放大镜效果、user_center_site.html里的地址表单验证,都是用它几行class搞定的。所有交互逻辑,比如购物车数量实时更新、地址选择下拉联动、轮播图自动切换,都写在独立的cart.jsuser_center_site.jsindex.js里,代码清晰,便于调试。这种“前后端不分离”的模式,对于初学者理解HTTP请求-响应周期、表单提交、页面跳转等Web基础概念,反而比SPA(单页应用)更直观。

  • 支付网关:支付宝官方沙箱环境
    这是最关键也最体现项目价值的一环。它没有接入任何第三方支付SDK的“黑盒”,而是直接使用支付宝开放平台提供的alipay-sdk-python官方SDK。沙箱环境意味着你不需要企业资质、不需要签约,只需在open.alipay.com注册一个开发者账号,创建一个沙箱应用,就能获得APP_ID私钥支付宝公钥三要素。项目里utils/alipay.py这个文件,就是整个支付逻辑的中枢,它封装了两个核心方法:get_pay_url()用于生成支付跳转链接,verify_sign()用于校验支付宝异步通知的签名真伪。这种“白盒化”的集成方式,让你能真正看懂支付背后的加密、验签、回调全过程,而不是对着一个pay()函数干瞪眼。

2.2 核心模块解耦:高内聚、低耦合的Django式组织

整个项目按Django App(应用)进行垂直切分,每个App负责一个明确的业务域,这是Django项目工程化的基石。

  • apps/user: 用户中心模块,包含User,Address模型,RegisterView,ActiveView,LoginView,LogoutView,UserInfoView,UserSiteView,UserOrderView等视图类。它与Django内置的auth系统深度集成,User模型继承自AbstractUser,扩展了passport(用户唯一标识)字段;Address模型则通过ForeignKey关联到User,并设置了default=True来标记默认收货地址。这种设计,让“一个用户多个地址”的业务需求,通过ORM一行代码就解决了。

  • apps/goods: 商品模块,核心是GoodsType,Goods,GoodsSKU,GoodsImage四个模型。这里有个精妙的设计:Goods是商品SPU(标准产品单元,如“iPhone 15”),GoodsSKU是商品SKU(库存量单位,如“iPhone 15 黑色 128GB”),GoodsImage则是一对多关系,一张商品可以有多张详情图。这种分层模型,是支撑后续“商品搜索”、“规格筛选”、“库存扣减”的底层基础。views.py里的IndexView,ListView,DetailView,分别对应首页、列表页、详情页,它们共享一套基于django.core.paginator的分页逻辑,?page=2&sort=price这样的URL参数,会被ListView自动解析并执行order_by('price')

  • apps/cart: 购物车模块,采用Session存储方案。为什么不存数据库?因为购物车本质是用户未提交的临时状态,Session天然具备时效性(默认2周过期)、安全性(服务端存储、客户端只存sessionid)、轻量性(无需额外DB查询)。CartAddView接收sku_idcount,先校验库存,再将(sku_id, count)以字典形式存入request.session['cart']CartInfoView则遍历这个字典,通过GoodsSKU.objects.get(id=sku_id)查出商品信息,组装成完整的购物车列表。整个过程没有一次数据库写操作,性能极高。

  • apps/order: 订单模块,是整个系统的“心脏”。它包含OrderInfo(订单主表,记录订单号、用户、总金额、支付状态)和OrderGoods(订单商品表,记录该订单买了哪些SKU、各多少件、单价)两个模型。OrderPlaceView负责渲染place_order.html,它会从Session中读取购物车数据,同时查询用户的收货地址列表,一并传给模板;OrderCommitView则是真正的下单动作,它在一个数据库事务(transaction.atomic())中,完成三件事:1)创建OrderInfo记录;2)遍历购物车,为每个SKU创建OrderGoods记录;3)清空当前用户的Session购物车。这三步必须原子性执行,否则就会出现“订单创建了但商品没记上”或者“商品记上了但订单没创建”的脏数据。

这种模块划分,让代码的可维护性极强。如果你想增加“收藏夹”功能,只需要新建一个apps/favorite,写自己的模型和视图,完全不影响其他模块。它不是把所有代码塞进一个views.py里,而是用Django的App机制,构建了一个清晰、可生长的代码宇宙。

3. 核心功能实现详解:从代码到业务逻辑的穿透式解读

3.1 用户系统:邮箱激活的完整闭环

用户注册与激活,是电商网站的第一道门槛,也是最容易出错的环节。这个项目把它做得非常扎实。

注册流程 (apps/user/views.py)
1. 用户在register.html填写用户名、邮箱、密码、确认密码。
2.RegisterView.post()方法接收到数据后,首先调用UserForm.is_valid()进行Django表单验证(检查邮箱格式、密码强度、两次输入是否一致)。
3. 验证通过后,关键一步来了:它没有直接调用form.save(),而是先user = form.save(commit=False),将用户对象暂存于内存,此时用户是is_active=False(未激活状态)。
4. 接着,生成一个唯一的激活令牌(token),项目里用的是itsdangerous.URLSafeTimedSerializer,它能把用户ID和时间戳加密成一个有时效性的字符串,比如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
5. 然后,构造一封激活邮件,邮件正文里包含一个形如http://127.0.0.1:8000/user/active/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...的链接。
6. 最后,调用send_mail()发送邮件。注意,这里的邮件后端配置在settings.py里,使用的是django.core.mail.backends.smtp.EmailBackend,你需要在settings.py中填入自己的SMTP服务器(如QQ邮箱的smtp.qq.com)和授权码。

激活流程 (apps/user/views.py)
1. 用户点击邮件里的链接,请求到达ActiveView.get()
2.ActiveView从URL中提取出token,然后用itsdangerousloads()方法对其进行解密。
3. 如果解密成功且未超时(默认1小时),就获取到原始的user_id,然后User.objects.get(id=user_id)找到用户对象。
4. 将该用户的is_active字段设为True,并调用user.save()
5. 最后,重定向到login.html,并带上一个?message=激活成功的参数,前端用{{ request.GET.message }}显示提示。

提示:itsdangerous是Django官方推荐的签名库,比自己用hashlib拼接字符串安全得多。它的TimedSerializer能自动处理过期时间,避免了手动计算时间戳和对比的繁琐。

登录态管理
登录成功后,Django的login()函数会自动将用户ID写入Session,并设置request.user为当前登录用户。所有需要登录才能访问的视图(如UserInfoView),都加上了@login_required装饰器,它会在用户未登录时,自动重定向到LOGIN_URL = '/user/login/'。Session的生命周期由SESSION_COOKIE_AGE(默认1209600秒,即2周)控制,这意味着用户关闭浏览器后,只要2周内再次访问,依然保持登录状态。

3.2 购物车系统:Session驱动的轻量级实现

购物车是用户行为的“暂存区”,它的设计直接影响用户体验和系统性能。

数据结构
购物车数据存储在request.session['cart']中,其结构是一个字典:

{ '1': 2, # sku_id为1的商品,数量为2 '3': 1, # sku_id为3的商品,数量为1 '5': 5, # sku_id为5的商品,数量为5 }

这个设计极其简洁,keyGoodsSKU.idvalue是购买数量。它规避了为购物车单独建表的复杂性,也避免了频繁的数据库读写。

增删改查逻辑 (apps/cart/views.py)
-添加 (CartAddView):接收sku_idcount。首先GoodsSKU.objects.get(id=sku_id)查出商品对象,校验count <= sku.stock(库存是否充足)。如果充足,则cart_dict = request.session.get('cart', {})cart_dict[sku_id] = cart_dict.get(sku_id, 0) + count,最后request.session['cart'] = cart_dict。注意,这里没有request.session.save(),因为Django默认会在响应时自动保存。
-查询 (CartInfoView):从Session中取出cart_dict,然后GoodsSKU.objects.filter(id__in=cart_dict.keys())批量查询所有商品信息,再遍历cart_dict,为每个商品对象附加count属性,最终传给模板。
-更新 (CartUpdateView):接收sku_id和新的count。逻辑与添加类似,但直接赋值cart_dict[sku_id] = count
-删除 (CartDeleteView):接收sku_id,直接del cart_dict[sku_id]

前端交互 (static/js/cart.js)
所有购物车操作都通过AJAX完成,页面无需刷新。例如,点击“+”按钮,JS会收集当前行的sku_id,然后发起一个POST请求到/cart/add/,携带{sku_id: 1, count: 1}。成功后,JS解析返回的JSON(包含新的总数量和总价格),并实时更新页面上的数字。这种“局部刷新”体验,远胜于传统的整页跳转。

3.3 订单流程:事务保障下的数据一致性

订单是电商系统的核心资产,其创建过程必须万无一失。

下单前 (OrderPlaceView)
这个视图是place_order.html的后端控制器。它做了三件事:
1. 从Session中读取购物车数据cart_dict
2. 批量查询这些SKU的商品信息skus = GoodsSKU.objects.filter(id__in=cart_dict.keys())
3. 查询当前用户的全部收货地址addresses = Address.objects.filter(user=request.user)
然后,将skusaddressescart_dict(用于计算每个SKU的数量)一并传给模板。模板里,用户可以选择一个地址,并看到清晰的订单预览(商品名、单价、数量、小计)。

下单中 (OrderCommitView)
这是整个流程中最关键的一步,它被包裹在一个数据库事务中:

from django.db import transaction class OrderCommitView(View): @transaction.atomic def post(self, request): # 1. 创建OrderInfo对象 order = OrderInfo.objects.create( order_id=order_id, user=request.user, addr=address, pay_method=pay_method, total_count=total_count, total_price=total_price, transit_price=transit_price ) # 2. 遍历购物车,创建OrderGoods对象 cart_dict = request.session.get('cart', {}) for sku_id, count in cart_dict.items(): sku = GoodsSKU.objects.get(id=sku_id) # 使用select_for_update()锁定该SKU记录,防止并发超卖 sku = GoodsSKU.objects.select_for_update().get(id=sku_id) if count > sku.stock: # 库存不足,抛出异常,事务回滚 raise Exception('库存不足') sku.stock -= count sku.sales += count sku.save() OrderGoods.objects.create( order=order, sku=sku, count=count, price=sku.price ) # 3. 清空购物车 del request.session['cart']

这段代码体现了两个重要思想:一是事务(atomic),确保订单主表和明细表要么全成功,要么全失败;二是悲观锁(select_for_update),在扣减库存前,先锁定数据库中对应的GoodsSKU记录,这样即使100个用户同时抢购同一款商品,数据库也会让它们排队执行,彻底杜绝了“超卖”问题。

3.4 支付宝沙箱支付:从跳转到回调的全流程打通

支付宝支付是这个项目的“高光时刻”,它完整实现了从用户下单到支付成功、再到网站更新订单状态的闭环。

支付跳转 (apps/order/views.py)
当用户在place_order.html点击“立即支付”按钮,会触发OrderCommitView创建订单,然后重定向到OrderPayViewOrderPayView的核心逻辑是调用alipay.get_pay_url()

def get_pay_url(self, order_id, total_pay): # 构造支付宝请求参数 params = { "out_trade_no": order_id, # 商户订单号,即我们的order_id "product_code": "FAST_INSTANT_TRADE_PAY", "total_amount": str(total_pay), # 订单总金额,字符串类型 "subject": "天天生鲜订单", # 订单标题 "return_url": "http://127.0.0.1:8000/order/checkpay/", # 同步回调地址 "notify_url": "http://127.0.0.1:8000/order/checkpay/", # 异步回调地址 } # 调用SDK生成支付链接 url = self.alipay.api_alipay_trade_page_pay(**params) return url

生成的url是一个完整的支付宝沙箱支付页面链接,用户点击后,会跳转到支付宝的模拟支付界面,输入沙箱买家账号(如2088102177842679)和密码(如111111),然后点击“确认付款”。

支付回调 (apps/order/views.py)
支付宝付款成功后,会向notify_url(异步)和return_url(同步)发送HTTP POST请求。项目只处理notify_url,因为它是可靠的、一定会到达的。

def post(self, request): # 1. 获取支付宝POST过来的全部数据 data = request.POST.dict() # 2. 从data中提取sign参数,并从data中移除它 sign = data.pop('sign', None) # 3. 调用alipay.verify_sign()方法,用支付宝公钥验证签名 if not self.alipay.verify_sign(data, sign): return HttpResponse('非法请求') # 4. 验证通过,提取关键业务参数 out_trade_no = data.get('out_trade_no') # 我们的订单号 trade_status = data.get('trade_status') # 交易状态 # 5. 根据交易状态更新订单 if trade_status == 'TRADE_SUCCESS': OrderInfo.objects.filter(order_id=out_trade_no).update( pay_method=3, # 支付宝支付 status=2 # 已支付 ) return HttpResponse('success') # 必须返回'success',否则支付宝会重试

这个回调逻辑,是整个支付环节的“守门员”。它通过严格的签名验证,确保请求确实来自支付宝,而非黑客伪造;它通过更新数据库,将订单状态从“待支付”变为“已支付”,完成了商业闭环。return HttpResponse('success')这一行至关重要,它告诉支付宝“我收到了”,支付宝就不会再重试发送通知。

4. 部署与运维:从本地开发到生产环境的平滑过渡

4.1 本地开发环境搭建:五分钟启动指南

部署这个项目,第一步永远是让它在你的电脑上跑起来。整个过程可以压缩到五分钟以内。

步骤1:安装Python与pip
确保你的系统已安装Python 3.6+。在终端输入python --version确认。pip通常随Python一起安装,若没有,去pypi.org下载get-pip.py安装。

步骤2:创建虚拟环境(强烈推荐)

# 进入项目根目录 cd dailyfresh # 创建名为venv的虚拟环境 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate.bat # macOS/Linux: source venv/bin/activate

虚拟环境能隔离项目依赖,避免不同项目间的Python包冲突。

步骤3:安装依赖
项目依赖都写在requirements.txt里(虽然输入描述里没提,但一个规范的Django项目必然有它)。如果没有,你可以根据settings.py中的INSTALLED_APPS推断,手动安装:

pip install django==2.2.28 pip install mysqlclient==2.1.1 pip install itsdangerous==2.1.2 pip install alipay-sdk-python==3.7.112 pip install Pillow==9.5.0 # 用于处理图片上传

步骤4:配置数据库
1. 安装MySQL(推荐使用Docker,一条命令docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7)。
2. 登录MySQL,创建数据库:CREATE DATABASE dailyfresh DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3. 导入初始数据:mysql -u root -p dailyfresh < dailyfresh.sql

步骤5:修改Django配置
打开dailyfresh/settings.py,找到数据库配置段:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': '3306', 'NAME': 'dailyfresh', 'USER': 'root', 'PASSWORD': '123456', } }

USERPASSWORD改成你MySQL的实际账号密码。

步骤6:运行开发服务器

# 迁移数据库(创建所有表) python manage.py migrate # 创建超级用户(用于访问Django Admin) python manage.py createsuperuser # 启动服务器 python manage.py runserver 0.0.0.0:8000

现在,打开浏览器访问http://127.0.0.1:8000,你就能看到一个活生生的电商网站了。

4.2 生产环境部署:uwsgi双实例的实战配置

开发服务器runserver只能用于调试,生产环境必须用更健壮的WSGI服务器。项目提供了uwsgi.iniuwsgi2.ini两个配置文件,这是典型的“主备”或“负载均衡”思路。

uwsgi.ini核心配置解析

[uwsgi] # Django项目路径 chdir = /path/to/dailyfresh # Python虚拟环境路径 home = /path/to/dailyfresh/venv # Django的wsgi入口模块 module = dailyfresh.wsgi:application # 进程数 processes = 4 # 线程数 threads = 2 # 监听的socket地址(Unix socket,高效) socket = /path/to/dailyfresh/uwsgi.sock # socket权限 chmod-socket = 666 # 主进程PID文件 pidfile = /path/to/dailyfresh/uwsgi.pid # 日志文件 logto = /path/to/dailyfresh/logs/uwsgi.log # 后台运行 daemonize = true

这个配置启动了一个拥有4个进程、每个进程2个线程的uwsgi服务,它通过Unix socket与Nginx通信。uwsgi2.ini则是一个几乎相同的副本,只是socketpidfile路径不同,可以用来启动第二个独立的服务实例,作为冗余备份。

Nginx反向代理配置 (/etc/nginx/conf.d/dailyfresh.conf)

upstream dailyfresh_backend { server unix:/path/to/dailyfresh/uwsgi.sock; # 如果启用了uwsgi2.ini,可以加上第二条 # server unix:/path/to/dailyfresh/uwsgi2.sock; } server { listen 80; server_name your-domain.com; location / { include uwsgi_params; uwsgi_pass dailyfresh_backend; # 传递真实IP给Django uwsgi_param HTTP_X_FORWARDED_FOR $remote_addr; } # 静态文件由Nginx直接服务,不走Django location /static/ { alias /path/to/dailyfresh/static/; } # 媒体文件(用户上传的图片) location /media/ { alias /path/to/dailyfresh/media/; } }

Nginx在这里扮演了“流量管家”的角色:它把用户的HTTP请求,转发给后端的uwsgi进程;它把/static//media/开头的请求,直接从磁盘读取文件返回,极大减轻了Django的负担;它还能做负载均衡、SSL终止、访问日志等高级功能。

4.3 关键配置与注意事项:那些文档里没写的坑

在实际部署中,有几个地方极易踩坑,是文档里往往一笔带过的,但却是决定项目能否上线的关键。

1. 静态文件收集 (collectstatic)
Django开发时,静态文件(CSS/JS/Images)直接放在各个App的static/目录下,由runserver自动提供。但在生产环境,Nginx需要一个集中的静态文件目录。因此,在部署前,必须执行:

python manage.py collectstatic --noinput

这条命令会把所有App下的static/文件,全部拷贝到settings.pySTATIC_ROOT指定的目录(如/path/to/dailyfresh/staticfiles/)。然后,Nginx的location /static/配置,就必须指向这个STATIC_ROOT目录,而不是源代码目录。

2. 时区与国际化
settings.pyTIME_ZONE = 'Asia/Shanghai'必须正确设置,否则订单创建时间、用户登录日志都会是UTC时间,导致排查问题时一头雾水。同时,USE_I18N = TrueUSE_L10N = True要开启,这样才能正确格式化日期、货币(如¥199.00)。

3. 安全加固
-DEBUG = False:这是生产环境的铁律。DEBUG=True会暴露详细的错误堆栈,可能泄露数据库密码等敏感信息。
-ALLOWED_HOSTS = ['your-domain.com', 'www.your-domain.com']:必须明确列出允许访问的域名,防止HTTP Host头攻击。
-SECRET_KEY:必须替换成一个长、随机、保密的字符串。绝不能使用settings.py里默认的'***'。可以用Python生成:python -c "import secrets; print(secrets.token_hex(32))"

4. 日志轮转
项目提供的日志配置,如果不加轮转,uwsgi.logdjango.log会无限增长,最终撑爆磁盘。建议在settings.py中配置logging,使用RotatingFileHandler

'handlers': { 'rotating_file': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/path/to/dailyfresh/logs/django.log', 'maxBytes': 1024*1024*5, # 5MB 'backupCount': 5, # 保留5个备份 'formatter': 'verbose', }, },

5. 常见问题与排查技巧实录:那些深夜调试时的真实战场

作为一个被无数学生和开发者反复蹂躏过的项目,它积累了一套高频问题清单。这些问题,往往不是代码bug,而是环境、配置、理解偏差导致的“假性故障”。

5.1 “页面打不开”系列:网络与配置的迷宫

问题现象可能原因排查与解决
http://127.0.0.1:8000显示This site can’t be reached1. Django开发服务器没启动
2. 端口被占用(如8000被其他程序占了)
3. 防火墙阻止了连接
1. 检查终端是否在运行python manage.py runserver
2.netstat -ano \| findstr :8000(Windows)或lsof -i :8000(macOS/Linux)查端口,用kill -9 PID结束占用进程
3. 临时关闭防火墙测试
http://127.0.0.1:8000显示DisallowedHost at /settings.pyALLOWED_HOSTS为空或未包含'127.0.0.1'ALLOWED_HOSTS改为['127.0.0.1', 'localhost']
Nginx访问显示502 Bad Gateway1. uwsgi进程没启动
2. uwsgi.sock文件权限不对
3. uwsgi配置中的chdirhome路径错误
1.ps aux \| grep uwsgi查看进程
2.ls -l /path/to/uwsgi.sock,确保Nginx用户(通常是www-datanginx)有读写权限,chmod 666 /path/to/uwsgi.sock
3. 检查uwsgi.ini中的路径是否绝对路径,且真实存在

5.2 “功能不工作”系列:逻辑与数据的陷阱

问题现象可能原因排查与解决
注册后收不到激活邮件1. SMTP配置错误(邮箱服务器、端口、授权码)
2. 邮箱被当成垃圾邮件
1. 在settings.py中检查EMAIL_BACKEND,EMAIL_HOST,EMAIL_PORT,EMAIL_HOST_USER,EMAIL_HOST_PASSWORD
2. 先用Python脚本测试邮件发送:python -c "from django.core.mail import send_mail; send_mail('test','test content','from@example.com',['to@example.com'],fail_silently=False)"
加入购物车后,页面数量不更新1.cart.js未被正确加载(检查浏览器F12的Network标签)
2. AJAX请求返回了错误(检查Console标签)
1. 查看base.html中是否引入了<script src="/static/js/cart.js"></script>
2. 在CartAddView.post()中,临时添加print(request.POST)return JsonResponse({'status': 'error', 'msg': 'xxx'}),查看控制台输出
支付宝回调后,订单状态没变1.notify_url地址在支付宝沙箱后台没配置对
2.alipay.verify_sign()失败(公钥错误)
3.OrderInfo.objects.filter(...).update()没生效(order_id不匹配)
1. 登录支付宝沙箱后台,检查“应用公钥”和“异步通知地址”是否与项目一致
2. 检查utils/alipay.pyapp_private_key_pathalipay_public_key_path指向的文件路径是否正确,文件内容是否是PEM格式的密钥
3. 在回调视图中,print(out_trade_no, trade_status),确认收到的订单号是否与数据库中的一致

5.3 “性能与安全”系列:上线前的终极考验

问题现象可能原因排查与解决
网站访问缓慢,尤其首页轮播图加载慢1. 静态文件未由Nginx直接提供
2. 图片未压缩,体积过大
1. 检查Nginx配置,确保location /static/块存在且alias路径正确
2. 使用工具(如TinyPNG)压缩static/images/下的所有图片
支付宝回调地址被恶意访问,导致订单状态被篡改checkpay/接口未做任何权限校验,任何人都能调用OrderCheckPayView.post()开头,添加IP白名单校验:
if request.META.get('REMOTE_ADDR') not in ['100.64.0.1', '100.64.0.2']: # 支付宝沙箱固定IP
return HttpResponseForbidden()

实操心得:我在帮一个学生部署时,他卡在“收不到邮件”上整整两天。最后发现,他用的是163邮箱,但EMAIL_HOST却填成了smtp.qq.com。这种低级错误,恰恰是新手最容易犯的。我的建议是,把所有配置项(数据库、邮箱、支付宝)都做成一个单独的local_settings.py文件,然后在settings.py末尾try...except ImportError导入它。这样,主配置文件干净,本地配置文件可以.gitignore掉,避免误提交敏感信息。

6. 项目拓展与学习路径:从“能跑”到“精通”的跃迁

这个项目的价值,远不止于“能跑起来”。它是一块绝佳的跳板,可以带你深入Django的方方面面。

6.1 功能增强:让MVP进化为MVP+

  • 增加微信支付:支付宝的逻辑已经铺好,微信支付的SDK(wechatpy)调用方式类似。你需要在utils/下新建wechat.py,封装get_pay_url()verify_sign(),然后在OrderPayViewOrderCheckPayView中,根据pay_method参数,动态选择调用支付宝还是微信的SDK。这能让你深刻理解“策略模式”在支付网关中的应用。

  • 实现商品搜索:目前的搜索是简单的GoodsSKU.objects.filter(name__icontains=q)。可以引入django-haystack+WhooshElasticsearch,实现全文检索、拼音搜索、相关度排序。这会带你进入搜索引擎的世界。

  • 添加后台管理系统:Django Admin已经为你准备好了admin.py。你可以为GoodsSKU,OrderInfo等模型注册Admin,然后通过list_display,list_filter,search_fields等属性,定制一个功能强大的运营后台,让非技术人员也能管理商品和订单。

6.2 技术深化:从“会用”到“懂原理”

  • 深入Django ORM:尝试将OrderCommitView中的事务逻辑,改写为使用select_related()prefetch_related()优化查询。比如,在查询OrderInfo时,用select_related('addr')一次性把地址信息查出来,避免N+1查询问题。这会让你对数据库查询优化有切肤之痛。

  • 理解中间件机制:项目中有一个middleware.py,里面实现了UserAuthMiddleware。你可以研究它如何在每次请求前,将request.user注入到请求对象中。然后,试着自己写一个VisitCountMiddleware,统计每个商品详情页的访问次数,并将其写入Redis,这就是一个简易的“热榜”功能。

  • 探索异步任务:将邮件发送、短信通知等耗时操作,从视图中剥离出来,交给Celery+Redis异步执行。这能让你理解“同步阻塞”与“异步非阻塞”的本质区别,是迈向高并发架构的第一步。

6.3 工程实践:从“个人项目”到“团队协作”

  • Git工作流:不要把所有代码都提交到master分支。建立dev(开发)、feature/*(功能分支)、release/*(发布分支)的规范。每次新增一个功能(如“微信支付”),都在feature/wechat-pay分支上开发,测试通过后,再合并到dev

  • Docker容器化:为项目编写Dockerfiledocker-compose.ymlDockerfile定义Python运行环境和依赖,docker-compose.yml定义MySQL、Redis、Nginx、uwsgi四个服务的启动顺序和网络连接。这样,任何人拿到代码,一句docker-compose up -d,就能一键启动整个环境,彻底消灭“在我机器上是好的”这类问题。

这个Django电商项目,就像一座精心建造的桥梁,一端连着你对Web开发的懵懂认知,另一端通向真实世界的复杂业务。它不承诺给你一个完美的、无懈可击的系统,但它毫无保留地展示了,一个合格的工程师,是如何用最朴实的工具,一步步搭建起一个可靠、可用、可演进的数字世界。当你亲手修复了第10个502 Bad Gateway,当你第一次看到支付宝沙箱的“支付成功”页面跳转回来,当你在Django Admin里,亲手把一个订单的状态从“待发货”改为“已发货”——那一刻,你收获的不仅是技能,更是作为一名创造者的笃定与自信。

本文还有配套的精品资源,点击获取

简介:这个Django电商项目开箱即用,基于Python 3.x和MySQL开发,已打通用户注册登录(支持邮箱激活)、地址管理、商品分类浏览、搜索与详情展示、新品推荐、购物车增删改查、下单流程、订单状态跟踪等核心环节。支付宝对接采用官方沙箱环境,支付跳转与回调逻辑完整可用。前端使用原生HTML/CSS/JS模板,无额外框架依赖;后端通过Django ORM操作数据库,附带dailyfresh.sql建表语句及初始化数据。部署方面提供uwsgi双实例配置(uwsgi.ini和uwsgi2.ini)、日志设置、pid文件管理,并包含首页轮播图、商品多维度排序(默认/价格/人气)、分页列表、用户浏览记录等细节功能。配套两份详细文档(项目说明文档.docx、python电商项目.docx)和页面功能说明文本,另有README.md和光影程序文档说明.txt辅助理解。所有页面如register.html、login.html、cart.html、place_order.html、user_center_info.html等均已实现并本地测试通过,适合课程设计、毕业设计或Django实战入门直接部署演示。


本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询