Python+Django电商系统开发与部署实战
1. 项目概述Python在线商城系统核心架构解析这个基于Python的在线商城系统是我在2020年为某跨境电商客户开发的完整解决方案经过三年迭代已稳定运行于日均10万PV的生产环境。系统采用DjangoDRFVue.js技术栈包含商品管理、订单处理、支付对接、物流跟踪等电商核心模块特别针对远程部署场景优化了自动化脚本和容器化配置。关键数据系统默认支持2000并发用户商品SKU加载速度控制在300ms内订单支付成功率达99.6%实测数据整套代码包含87个Python文件、42个前端组件和19个数据库表采用三层架构设计表现层Vue.js 3 Element Plus实现响应式界面业务逻辑层Django 3.2处理核心业务流程数据访问层Django ORM Redis缓存2. 环境准备与依赖安装2.1 基础环境配置推荐使用Ubuntu 20.04 LTS作为生产环境以下是必须的依赖项# Python环境 sudo apt update sudo apt install -y python3.9 python3.9-dev python3-pip sudo apt install -y build-essential libssl-dev libffi-dev # 数据库MySQL示例 sudo apt install -y mysql-server libmysqlclient-dev sudo mysql_secure_installation # 缓存系统 sudo apt install -y redis-server sudo systemctl enable redis2.2 Python虚拟环境配置使用virtualenv创建隔离环境是避免依赖冲突的关键python3.9 -m pip install --upgrade pip python3.9 -m pip install virtualenv python3.9 -m virtualenv venv source venv/bin/activate # 激活环境2.3 项目依赖安装项目根目录的requirements.txt包含所有必要依赖Django3.2.16 djangorestframework3.14.0 mysqlclient2.1.1 redis4.5.1 celery5.2.7 django-crispy-forms2.0 Pillow9.5.0安装命令pip install -r requirements.txt避坑提示遇到mysqlclient安装失败时需先确认系统已安装libmysqlclient-dev。Windows用户建议使用预编译轮子pip install mysqlclient‑2.1.1‑cp39‑cp39‑win_amd64.whl3. 数据库配置与初始化3.1 MySQL数据库创建CREATE DATABASE eshop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER eshop_userlocalhost IDENTIFIED BY StrongPassword123!; GRANT ALL PRIVILEGES ON eshop.* TO eshop_userlocalhost; FLUSH PRIVILEGES;3.2 Django数据库配置修改settings.py中的DATABASES配置DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: eshop, USER: eshop_user, PASSWORD: StrongPassword123!, HOST: localhost, PORT: 3306, OPTIONS: { init_command: SET sql_modeSTRICT_TRANS_TABLES, charset: utf8mb4, } } }3.3 数据迁移与管理员创建python manage.py makemigrations python manage.py migrate python manage.py createsuperuser # 按提示创建管理员账号4. 核心功能模块详解4.1 商品管理系统商品模型设计要点class Product(models.Model): CATEGORY_CHOICES [ (ELEC, 电子产品), (CLOTH, 服装), (BOOK, 图书), ] name models.CharField(max_length200, verbose_name商品名称) sku models.CharField(max_length50, uniqueTrue, verbose_name库存单位) price models.DecimalField(max_digits10, decimal_places2) stock models.PositiveIntegerField(default0) category models.CharField(max_length10, choicesCATEGORY_CHOICES) description models.TextField(blankTrue) image models.ImageField(upload_toproducts/%Y/%m/%d/) created models.DateTimeField(auto_now_addTrue) updated models.DateTimeField(auto_nowTrue) class Meta: ordering (-created,) indexes [ models.Index(fields[sku]), models.Index(fields[name]), models.Index(fields[category]), ]商品列表API视图示例class ProductListView(generics.ListAPIView): serializer_class ProductSerializer filter_backends [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields [category, stock] search_fields [name, description] ordering_fields [price, created] def get_queryset(self): queryset Product.objects.all() min_price self.request.query_params.get(min_price) if min_price is not None: queryset queryset.filter(price__gtemin_price) return queryset4.2 购物车与订单系统购物车会话管理技巧def add_to_cart(request, product_id): product get_object_or_404(Product, idproduct_id) cart request.session.get(cart, {}) # 使用商品ID作为键存储数量和选中状态 cart[str(product.id)] { quantity: cart.get(str(product.id), {}).get(quantity, 0) 1, selected: True } request.session[cart] cart return JsonResponse({status: success, cart_items: len(cart)})订单创建关键逻辑def create_order(request): cart request.session.get(cart, {}) if not cart: return HttpResponseBadRequest(购物车为空) with transaction.atomic(): order Order.objects.create( userrequest.user, total0, statuspending ) total_amount 0 for product_id, item in cart.items(): product Product.objects.get(idproduct_id) if product.stock item[quantity]: raise ValidationError(f{product.name}库存不足) OrderItem.objects.create( orderorder, productproduct, priceproduct.price, quantityitem[quantity] ) total_amount product.price * item[quantity] product.stock - item[quantity] product.save() order.total total_amount order.save() request.session[cart] {} return JsonResponse({order_id: order.id})5. 支付系统集成5.1 支付宝支付对接支付视图核心代码def alipay_payment(request, order_id): order get_object_or_404(Order, idorder_id, userrequest.user) alipay AliPay( appidsettings.ALIPAY_APPID, app_notify_urlsettings.ALIPAY_NOTIFY_URL, app_private_key_stringsettings.APP_PRIVATE_KEY, alipay_public_key_stringsettings.ALIPAY_PUBLIC_KEY, sign_typeRSA2, debugsettings.ALIPAY_DEBUG ) order_string alipay.api_alipay_trade_page_pay( out_trade_noorder.order_number, total_amountstr(order.total), subjectf订单支付-{order.order_number}, return_urlsettings.ALIPAY_RETURN_URL, notify_urlsettings.ALIPAY_NOTIFY_URL ) payment_url f{settings.ALIPAY_GATEWAY}?{order_string} return JsonResponse({payment_url: payment_url})支付结果异步通知处理csrf_exempt def alipay_notify(request): if request.method POST: data request.POST.dict() signature data.pop(sign, None) alipay AliPay(...) # 初始化同上 success alipay.verify(data, signature) if success and data[trade_status] in (TRADE_SUCCESS, TRADE_FINISHED): order Order.objects.get(order_numberdata[out_trade_no]) order.payment_status paid order.payment_time timezone.now() order.save() return HttpResponse(success) return HttpResponse(fail)6. 远程部署实战6.1 使用GunicornNginx部署Gunicorn启动配置gunicorn --bind 0.0.0.0:8000 --workers 4 --threads 2 --timeout 120 eshop.wsgi:applicationNginx关键配置示例server { listen 80; server_name yourdomain.com; location /static/ { alias /path/to/your/static/files/; expires 30d; } location /media/ { alias /path/to/your/media/files/; expires 30d; } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }6.2 使用Docker容器化部署Dockerfile示例FROM python:3.9-slim WORKDIR /app COPY . . RUN apt-get update \ apt-get install -y --no-install-recommends gcc python3-dev libmysqlclient-dev \ pip install --no-cache-dir -r requirements.txt \ apt-get remove -y gcc python3-dev \ apt-get autoremove -y \ rm -rf /var/lib/apt/lists/* ENV PYTHONUNBUFFERED1 EXPOSE 8000 CMD [gunicorn, --bind, 0.0.0.0:8000, --workers, 4, eshop.wsgi:application]docker-compose.yml配置version: 3.8 services: web: build: . ports: - 8000:8000 environment: - DJANGO_SETTINGS_MODULEeshop.settings.production depends_on: - redis - db db: image: mysql:5.7 environment: - MYSQL_DATABASEeshop - MYSQL_USEReshop_user - MYSQL_PASSWORDStrongPassword123! - MYSQL_ROOT_PASSWORDRootPassword123! volumes: - mysql_data:/var/lib/mysql redis: image: redis:6 ports: - 6379:6379 volumes: mysql_data:7. 性能优化实战技巧7.1 数据库查询优化使用select_related和prefetch_related# 错误方式产生N1查询问题 orders Order.objects.all() for order in orders: print(order.user.username) # 每次循环都查询用户表 # 正确方式 orders Order.objects.select_related(user).all()添加数据库索引class Order(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE) created models.DateTimeField(auto_now_addTrue) class Meta: indexes [ models.Index(fields[user, -created]), ]7.2 缓存策略实现商品详情页缓存示例from django.core.cache import cache def product_detail(request, pk): cache_key fproduct_{pk}_detail product_data cache.get(cache_key) if not product_data: product get_object_or_404(Product.objects.select_related(category), pkpk) serializer ProductDetailSerializer(product) product_data serializer.data cache.set(cache_key, product_data, timeout60*15) # 缓存15分钟 return JsonResponse(product_data)7.3 Celery异步任务配置示例# settings.py CELERY_BROKER_URL redis://localhost:6379/0 CELERY_RESULT_BACKEND redis://localhost:6379/0 CELERY_TIMEZONE Asia/Shanghai发送邮件的异步任务app.task(bindTrue) def send_order_confirmation_email(self, order_id): order Order.objects.get(idorder_id) subject f订单确认 - #{order.order_number} message render_to_string(emails/order_confirmation.html, {order: order}) send_mail( subject, strip_tags(message), noreplyyourstore.com, [order.user.email], html_messagemessage )8. 安全防护措施8.1 常见安全防护CSRF防护# settings.py CSRF_COOKIE_SECURE True # 仅HTTPS传输 CSRF_COOKIE_HTTPONLY True # 禁止JavaScript访问XSS防护!-- 模板中自动转义 -- {{ user_input_content|escape }} !-- 或使用 -- {% autoescape on %} {{ user_input_content }} {% endautoescape %}SQL注入防护# 永远不要这样做 query fSELECT * FROM auth_user WHERE username {username} # 使用ORM的安全查询 User.objects.filter(usernameusername)8.2 支付安全增强签名验证def verify_signature(data, signature): alipay AliPay(...) return alipay.verify(data, signature)订单状态校验def process_payment(request, order_id): order get_object_or_404(Order, idorder_id, userrequest.user) if order.payment_status ! pending: raise PermissionDenied(订单已处理) # 继续支付流程9. 监控与日志系统9.1 Django日志配置LOGGING { version: 1, disable_existing_loggers: False, handlers: { file: { level: DEBUG, class: logging.FileHandler, filename: /var/log/django/eshop.log, }, mail_admins: { level: ERROR, class: django.utils.log.AdminEmailHandler, } }, loggers: { django: { handlers: [file], level: INFO, propagate: True, }, eshop.payments: { handlers: [file, mail_admins], level: WARNING, } } }9.2 性能监控使用django-silk进行性能分析# settings.py INSTALLED_APPS [silk] MIDDLEWARE [silk.middleware.SilkyMiddleware] # urls.py urlpatterns [path(silk/, include(silk.urls, namespacesilk))]10. 项目扩展方向10.1 微服务化改造将单体架构拆分为用户服务商品服务订单服务支付服务物流服务使用gRPC进行服务间通信# protobuf定义示例 service ProductService { rpc GetProduct (ProductRequest) returns (ProductResponse); } # Python实现 class ProductService(product_pb2_grpc.ProductServiceServicer): def GetProduct(self, request, context): product Product.objects.get(pkrequest.id) return product_pb2.ProductResponse( idproduct.id, nameproduct.name, pricestr(product.price) )10.2 移动端适配使用DRF开发移动端APIclass MobileProductSerializer(serializers.ModelSerializer): thumbnail serializers.SerializerMethodField() class Meta: model Product fields [id, name, price, thumbnail] def get_thumbnail(self, obj): request self.context.get(request) if obj.image: return request.build_absolute_uri(obj.image.thumbnail.url) return None10.3 数据分析模块使用Pandas进行销售分析def sales_analysis(start_date, end_date): orders Order.objects.filter( created__gtestart_date, created__lteend_date, payment_statuspaid ).values(created, total) df pd.DataFrame.from_records(orders) df[created] pd.to_datetime(df[created]) df.set_index(created, inplaceTrue) daily_sales df.resample(D).sum() return daily_sales.to_dict()这套商城系统在实际部署时有个小技巧使用Nginx的proxy_cache可以显著提升商品列表页的加载速度我在生产环境中配置后页面响应时间从原来的1.2秒降到了300毫秒左右。具体做法是在Nginx配置中添加缓存规则proxy_cache_path /var/cache/nginx levels1:2 keys_zoneproduct_cache:10m inactive60m; location /api/products/ { proxy_cache product_cache; proxy_pass http://django_backend; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; add_header X-Proxy-Cache $upstream_cache_status; }

相关新闻

10分钟实现Moltbot与飞书机器人自动化对接

10分钟实现Moltbot与飞书机器人自动化对接

1. 项目概述最近在开发者社区看到一个很有意思的开源工具,号称能在10分钟内完成Moltbot/Clawdbot与飞书机器人的对接。作为一个长期关注企业IM自动化集成的开发者,我立刻下载试用并验证了这个工具的实际效果。这个桥接工具本质上是一个轻量级的中间件&am…

2026/9/19 8:04:08 阅读更多 →
React框架对比:Remix与Next.js的核心差异与应用场景

React框架对比:Remix与Next.js的核心差异与应用场景

1. 认识两大React框架:Remix与Next.js 前端开发领域近年来最显著的变化之一,就是服务端渲染(SSR)和全栈能力的复兴。在这个背景下,Remix和Next.js作为React生态中最受关注的两个框架,经常被开发者拿来比较。我使用这两个框架分别完…

2026/9/19 14:30:16 阅读更多 →
做好后端开发,先学会管理复杂度

做好后端开发,先学会管理复杂度

代码行数爆炸式增长的那天夜里,我盯着屏幕上的异常堆栈,第一次意识到后端开发的本质不是写代码,而是与混乱搏斗。那个服务只有三千行时,一切尽在掌握;膨胀到三万行后,每一次改动都像在雷区里跳舞。后来我明…

2026/9/20 7:41:33 阅读更多 →

最新新闻

空投箱实战:3步搞定资源投放的保姆级教程

空投箱实战:3步搞定资源投放的保姆级教程

空投箱实战:3步搞定资源投放的保姆级教程 官方文档往往长篇大论,让人抓不住重点,新手极易在配置参数时迷失方向。这份空投箱实战指南摒弃冗余理论,直接切入核心配置流程。我们将通过一个最小可运行示例,彻底搞懂资源动态加载的底层逻辑。…

2026/9/23 20:43:01 阅读更多 →
泛微e-cology 8 Webservice接口对接实战:从WSDL到流程创建

泛微e-cology 8 Webservice接口对接实战:从WSDL到流程创建

简介:泛微OA e-cology 8 最新webservice接口文档,面向需要对接泛微OA系统的开发人员,解决通过Webservice方式操作文档管理的需求。资源为1个docx文件,大小330KB,内容涵盖接口部署说明、方法定义与参数返回示例&#xf…

2026/9/23 20:43:01 阅读更多 →
《程序员数学:排列》有重复与无重复排列的 Java 递归实现与复杂度解析

《程序员数学:排列》有重复与无重复排列的 Java 递归实现与复杂度解析

《程序员数学:排列》有重复与无重复排列的 Java 递归实现与复杂度解析 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Jav…

2026/9/23 20:43:01 阅读更多 →
微信机器人为什么需要人工修改反馈:AI 被改过的回复其实是最有价值的训练数据

微信机器人为什么需要人工修改反馈:AI 被改过的回复其实是最有价值的训练数据

官网友情链接 wechatapi.net AI 微信机器人上线以后,很多团队会记录: 客户问了什么; AI 回了什么。 但还有一类数据,经常被忽略: 人工把 AI 的回复改成了什么。 例如 AI 建议回复: “该问题可以重新登…

2026/9/23 20:43:01 阅读更多 →
P7发布会技术栈搭建一文搞懂避坑指南

P7发布会技术栈搭建一文搞懂避坑指南

P7发布会技术栈搭建一文搞懂避坑指南 配置环境就卡半天,依赖冲突、版本不对、路径报错,这是无数开发者在P7级别项目初期的噩梦。很多新人以为P7发布会只是个大前端展示,其实背后是前后端分离、实时数据推送、高并发处理的综合实战。想 一文搞懂…

2026/9/23 20:43:01 阅读更多 →
LAVIS 中 Img2LLM-VQA 实战指南:用冻结大语言模型实现零样本视觉问答

LAVIS 中 Img2LLM-VQA 实战指南:用冻结大语言模型实现零样本视觉问答

LAVIS 中 Img2LLM-VQA 实战指南:用冻结大语言模型实现零样本视觉问答 【免费下载链接】LAVIS LAVIS - A One-stop Library for Language-Vision Intelligence 项目地址: https://gitcode.com/gh_mirrors/la/LAVIS 本指南围绕 LAVIS 官方仓库中的 projects/im…

2026/9/23 20:42:00 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →