使用 Django 开发电子商务程序是一个系统性的过程,需要结合 Django 的 MVT(Model-View-Template)架构、第三方库以及电商业务逻辑。以下是一个分步指南,帮助你构建一个基础的电商系统:
1. 环境准备
首先确保安装了必要的工具:
bash
# 安装 Python(建议 3.8+)
# 安装 Django 和依赖库
pip install django djangorestframework pillow django-filter django-crispy-forms stripe # stripe 用于支付处理
2. 项目初始化
创建 Django 项目和应用:
bash
# 创建项目
django-admin startproject ecommerce
cd ecommerce
# 创建核心应用(商品、订单、用户等)
python manage.py startapp products
python manage.py startapp orders
python manage.py startapp users
在 ecommerce/settings.py 中注册应用:
python
INSTALLED_APPS = [
# Django 内置
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
# 第三方
'rest_framework',
'crispy_forms',
# 自定义应用
'products',
'orders',
'users',
]
# 配置模板和静态文件路径(可选,默认已配置)
CRISPY_TEMPLATE_PACK = 'bootstrap4' # 美化表单
3. 数据模型设计(Models)
电商核心模型包括商品、分类、订单、购物车、用户等,以下是关键模型示例:
3.1 商品模型(products/models.py)
python
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True) # 用于 URL
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='products/')
stock = models.PositiveIntegerField(default=0)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
3.2 订单模型(orders/models.py)
python
from django.db import models
from django.conf import settings
from products.models import Product
class Order(models.Model):
STATUS_CHOICES = (
('pending', 'Pending'),
('paid', 'Paid'),
('shipped', 'Shipped'),
('delivered', 'Delivered'),
('cancelled', 'Cancelled'),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
full_name = models.CharField(max_length=100)
email = models.EmailField()
address = models.CharField(max_length=250)
phone = models.CharField(max_length=20)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return f'Order {self.id}'
@property
def total_cost(self):
return sum(item.total_price for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='order_items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2) # 记录下单时的价格
quantity = models.PositiveIntegerField(default=1)
@property
def total_price(self):
return self.price * self.quantity
3.3 购物车(可使用 Session 或模型)
简单场景下用 Session 存储购物车,复杂场景(如登录用户保存购物车)可建模型:
python
# orders/models.py(可选,用户购物车模型)
class Cart(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
class CartItem(models.Model):
cart = models.ForeignKey(Cart, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
4. 数据库迁移
bash
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 执行迁移
5. 视图与业务逻辑(Views)
使用 Django 的 View 或 ListView/DetailView 等通用视图处理请求。
5.1 商品列表与详情(products/views.py)
python
from django.views.generic import ListView, DetailView
from .models import Product, Category
class ProductListView(ListView):
model = Product
template_name = 'products/product_list.html'
context_object_name = 'products'
class ProductDetailView(DetailView):
model = Product
template_name = 'products/product_detail.html'
context_object_name = 'product'
5.2 购物车操作(orders/views.py)
python
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from products.models import Product
@login_required
def add_to_cart(request, product_id):
product = get_object_or_404(Product, id=product_id)
cart, created = Cart.objects.get_or_create(user=request.user)
cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product)
if not created:
cart_item.quantity += 1
cart_item.save()
return redirect('cart_detail')
@login_required
def cart_detail(request):
cart = Cart.objects.get_or_create(user=request.user)[0]
return render(request, 'orders/cart_detail.html', {'cart': cart})
6. URL 配置
项目级 URLs(ecommerce/urls.py)
python
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('products/', include('products.urls')),
path('orders/', include('orders.urls')),
path('accounts/', include('users.urls')), # 用户相关(登录、注册等)
]
# 开发环境下提供媒体文件访问
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
应用级 URLs(products/urls.py)
python
from django.urls import path
from . import views
urlpatterns = [
path('', views.ProductListView.as_view(), name='product_list'),
path('<slug:slug>/', views.ProductDetailView.as_view(), name='product_detail'),
]
7. 模板(Templates)
创建 HTML 模板渲染页面,使用 Django 模板语法传递数据。例如商品详情页(products/templates/products/product_detail.html):
html
{% extends 'base.html' %}
{% block content %}
<h1>{{ product.name }}</h1>
<img src="{{ product.image.url }}" alt="{{ product.name }}">
<p>Price: ${{ product.price }}</p>
<p>{{ product.description }}</p>
<form action="{% url 'add_to_cart' product.id %}" method="post">
{% csrf_token %}
<button type="submit">Add to Cart</button>
</form>
{% endblock %}
8. 支付集成(以 Stripe 为例)
-
在
settings.py中配置 Stripe 密钥:pythonSTRIPE_PUBLIC_KEY = 'your_publishable_key' STRIPE_SECRET_KEY = 'your_secret_key' -
订单支付视图(
orders/views.py):pythonimport stripe from django.conf import settings from django.views.decorators.csrf import csrf_exempt from django.http import JsonResponse stripe.api_key = settings.STRIPE_SECRET_KEY @login_required def checkout(request): cart = Cart.objects.get(user=request.user) total = cart.items.aggregate(total=models.Sum(models.F('quantity') * models.F('product__price')))['total'] # 创建 Stripe 支付意向 intent = stripe.PaymentIntent.create( amount=int(total * 100), # 金额以分为单位 currency='usd' ) return render(request, 'orders/checkout.html', { 'client_secret': intent.client_secret, 'total': total }) @csrf_exempt def payment_success(request): # 处理支付成功逻辑(更新订单状态等) return JsonResponse({'status': 'success'})
9. 后台管理(Admin)
注册模型到 Django 后台,方便管理商品和订单:
python
# products/admin.py
from django.contrib import admin
from .models import Product, Category
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)} # 自动生成 slug
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
list_filter = ('available', 'category')
list_display = ('name', 'price', 'available')
10. 扩展功能
- 用户认证 :使用 Django 内置
auth或django-allauth实现登录、注册、权限管理。 - 搜索功能 :集成
django-filter或 Elasticsearch 实现商品搜索。 - 评价系统 :添加
Review模型关联商品和用户。 - 优惠券 :创建
Coupon模型实现折扣功能。 - 响应式设计:使用 Bootstrap 或 Tailwind CSS 优化前端。
部署
开发完成后,可部署到服务器(如 AWS、Heroku、DigitalOcean),注意:
- 关闭
DEBUG = False - 配置
ALLOWED_HOSTS - 使用
whitenoise处理静态文件 - 配置生产环境数据库(如 PostgreSQL)
通过以上步骤,你可以构建一个基础的 Django 电商系统,后续可根据需求逐步扩展功能。