作为一个全栈电商项目,服饰商城系统需要同时兼顾前端用户体验和后端稳定性。在技术选型上,我们采用Vue.js+Django的组合方案,这是经过多个线上项目验证的可靠架构。
前端选择Vue.js 3.x版本,主要考虑其以下优势:
后端选择Django REST framework主要基于:
开发环境配置建议:
采用经典的前后端分离模式:
code复制├── frontend/ # Vue前端项目
│ ├── public/ # 静态资源
│ ├── src/ # 源码目录
│ │ ├── api/ # 接口封装
│ │ ├── assets/ # 静态资源
│ │ ├── components/ # 公共组件
│ │ ├── router/ # 路由配置
│ │ ├── store/ # 状态管理
│ │ └── views/ # 页面组件
│
└── backend/ # Django后端项目
├── config/ # 项目配置
├── apps/ # 应用模块
│ ├── user/ # 用户模块
│ ├── product/ # 商品模块
│ ├── order/ # 订单模块
│ └── payment/ # 支付模块
├── manage.py # 管理脚本
└── requirements.txt # 依赖文件
核心表关系设计原则:
关键索引设置:
python复制class Product(models.Model):
name = models.CharField(max_length=100, db_index=True) # 商品名称索引
category = models.ManyToManyField(Category)
price = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
indexes = [
models.Index(fields=['price']), # 价格区间查询索引
]
采用JWT认证流程:
Django后端实现示例:
python复制# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': True
}
两种搜索方案对比:
python复制Product.objects.filter(name__icontains=keyword)
python复制# 安装django-elasticsearch-dsl
class ProductDocument(Document):
name = TextField(analyzer='ik_max_word')
description = TextField(analyzer='ik_max_word')
class Django:
model = Product
fields = ['price', 'category']
# 搜索实现
s = ProductDocument.search().query('multi_match', query=keyword, fields=['name', 'description'])
response = s.execute()
混合存储策略:
Vue实现示例:
javascript复制// 购物车状态管理
const useCartStore = defineStore('cart', {
state: () => ({
items: loadFromLocalStorage() || []
}),
actions: {
async syncWithServer() {
if (isLoggedIn()) {
const serverItems = await api.getCartItems()
this.items = mergeItems(this.items, serverItems)
this.saveToServer()
}
}
}
})
关键安全措施:
python复制# 支付回调处理
@csrf_exempt
def alipay_callback(request):
data = request.POST.dict()
# 验证签名
if not alipay.verify(data):
return HttpResponseForbidden()
# 处理业务逻辑
order = Order.objects.get(order_no=data['out_trade_no'])
if order.amount != Decimal(data['total_amount']):
return HttpResponseBadRequest('金额不匹配')
# 更新订单状态
order.status = 'paid'
order.save()
return HttpResponse('success')
html复制<img v-lazy="product.image" alt="商品图片">
vue复制<RecycleScroller
:items="products"
:item-size="200"
key-field="id"
>
<template #default="{ item }">
<ProductCard :product="item" />
</template>
</RecycleScroller>
多级缓存设计:
python复制# 商品详情缓存装饰器
def cache_product_detail(timeout=300):
def decorator(func):
@wraps(func)
def wrapper(request, product_id):
cache_key = f'product_{product_id}'
data = cache.get(cache_key)
if not data:
data = func(request, product_id)
cache.set(cache_key, data, timeout)
return data
return wrapper
return decorator
python复制products = Product.objects.filter(
category=category_id
).cache(ops=['get', 'fetch'], timeout=60*5)
python复制# settings.py
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_COOKIE_HTTPONLY = True
python复制from django.contrib.auth.hashers import make_password
user.password = make_password(password) # 使用PBKDF2算法
Docker-compose配置示例:
yaml复制version: '3'
services:
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
volumes:
- pg_data:/var/lib/postgresql/data
redis:
image: redis:6
backend:
build: ./backend
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./backend:/code
depends_on:
- db
- redis
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
volumes:
pg_data:
GitLab CI配置示例:
yaml复制stages:
- test
- build
- deploy
backend_test:
stage: test
script:
- cd backend
- python manage.py test
frontend_build:
stage: build
script:
- cd frontend
- npm install
- npm run build
artifacts:
paths:
- frontend/dist
deploy_prod:
stage: deploy
script:
- docker-compose up -d --build
only:
- main
javascript复制// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true
}
}
}
}
nginx复制location /api {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
}
python复制# settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
]
python复制# 安装django-prometheus
INSTALLED_APPS += ['django_prometheus']
MIDDLEWARE = [
'django_prometheus.middleware.PrometheusBeforeMiddleware',
# ...其他中间件
'django_prometheus.middleware.PrometheusAfterMiddleware'
]
bash复制python manage.py squashmigrations app_name migration_number
这个项目从技术选型到部署上线,每个环节都需要仔细考量。特别是在电商领域,支付流程的可靠性和数据安全性至关重要。在实际开发中,建议采用迭代开发模式,先实现核心功能再逐步完善细节。