IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我也会在其它平台持续发布最新文章,助你少走弯路。
大家好,我是IT策士。前面三节课我们把模型建好、索引加好、迁移理顺了,数据库里现在还是“空荡荡”的。今天我们就来做两件大事:把 Django Admin 变成运营人员的利器,同时给数据库灌入第一批数据,让项目有点“活气儿”。
Django Admin 是 Django 最引以为傲的“杀手锏”之一。你只需要写很少的代码,就能得到一个功能完整的后台管理系统。电商项目里,管理员需要上下架商品、查看订单、管理用户,这些都可以在 Admin 中实现。
一、创建超级管理员账号
要登录 Admin,首先需要一个超级用户。在项目根目录执行:
python manage.py createsuperuser按提示输入用户名、邮箱、密码:
Username(leave blank to use'kali'): admin Email address: admin@example.com Password: Password(again): Superuser created successfully.现在启动开发服务器:
python manage.py runserver访问http://127.0.0.1:8000/admin/,用刚创建的用户名和密码登录,你会看到 Django 自带的后台界面,目前只显示了默认的“用户”和“组”。这是因为我们还没有把自定义模型注册进去。
二、注册模型到 Admin
2.1 用户模块
编辑apps/users/admin.py:
from django.contribimportadmin from django.contrib.auth.adminimportUserAdmin as BaseUserAdmin from .modelsimportUser, Address @admin.register(User)class UserAdmin(BaseUserAdmin):# 在列表页显示的字段list_display=('id','username','phone','email','is_staff','is_active','date_joined')# 可按哪些字段筛选list_filter=('is_staff','is_active')# 搜索字段search_fields=('username','phone','email')# 编辑页分组fieldsets=BaseUserAdmin.fieldsets +(('额外信息',{'fields':('phone','email_active')}),)@admin.register(Address)class AddressAdmin(admin.ModelAdmin): list_display=('id','user','receiver','phone','province','city','district','is_default')search_fields=('receiver','phone')list_filter=('province','city')2.2 商品模块
编辑apps/products/admin.py:
from django.contribimportadmin from .modelsimportCategory, SPU, SKU, ProductImage class SKUInline(admin.TabularInline):"""在 SPU 详情页内嵌 SKU 编辑""" model=SKU extra=1# 默认显示一个空白行class ProductImageInline(admin.TabularInline):"""在 SKU 详情页内嵌图片编辑""" model=ProductImage extra=1@admin.register(Category)class CategoryAdmin(admin.ModelAdmin): list_display=('id','name','parent','level','sort','is_active')list_filter=('is_active','level')search_fields=('name',)@admin.register(SPU)class SPUAdmin(admin.ModelAdmin): list_display=('id','name','brand','category','create_time')search_fields=('name','brand')list_filter=('category',)inlines=[SKUInline]# 内嵌 SKU 管理@admin.register(SKU)class SKUAdmin(admin.ModelAdmin): list_display=('id','name','spu','price','stock','sales','is_active')search_fields=('name',)list_filter=('is_active','spu__category')inlines=[ProductImageInline]# 内嵌图片管理# 可以在列表页直接编辑上下架状态list_editable=('is_active','price')@admin.register(ProductImage)class ProductImageAdmin(admin.ModelAdmin): list_display=('id','sku','image','is_main','sort')2.3 购物车模块
编辑apps/cart/admin.py:
from django.contribimportadmin from .modelsimportCartItem @admin.register(CartItem)class CartItemAdmin(admin.ModelAdmin): list_display=('id','user','sku','quantity','is_checked','create_time')list_filter=('is_checked',)search_fields=('user__username','sku__name')2.4 订单模块
编辑apps/orders/admin.py:
from django.contribimportadmin from .modelsimportOrder, OrderItem class OrderItemInline(admin.TabularInline): model=OrderItem extra=0readonly_fields=('sku_name','sku_specs','price','quantity')@admin.register(Order)class OrderAdmin(admin.ModelAdmin): list_display=('id','order_no','user','total_amount','status','create_time')list_filter=('status','create_time')search_fields=('order_no','user__username')readonly_fields=('order_no','address_snapshot','create_time','update_time')inlines=[OrderItemInline]# 可在此处添加自定义操作(如批量改为“已发货”等)@admin.register(OrderItem)class OrderItemAdmin(admin.ModelAdmin): list_display=('id','order','sku_name','price','quantity')search_fields=('sku_name','order__order_no')2.5 支付模块
编辑apps/payment/admin.py:
from django.contribimportadmin from .modelsimportPayment @admin.register(Payment)class PaymentAdmin(admin.ModelAdmin): list_display=('id','order','trade_no','amount','status','create_time')list_filter=('status',)search_fields=('trade_no','order__order_no')readonly_fields=('order','create_time','update_time')保存所有文件后,刷新 Admin 页面,你会看到左侧导航栏出现了我们自定义的五个模块:用户、地址、分类、SPU、SKU、图片、购物车、订单、订单商品、支付记录。整个后台瞬间有模有样了。
三、Admin 高级定制——让后台更好用
3.1list_display也能显示关联字段
在SKUAdmin中我们用spu__category实现了跨表显示:
list_filter=('is_active','spu__category')这相当于在 SQL 中做了 JOIN,无需额外写代码。
3.2 使用list_editable实现列表页快速编辑
list_editable=('is_active','price')这样在 SKU 列表页就可以直接勾选“是否上架”或修改价格,无需点进详情页。
3.3 自定义 Admin 操作
在OrderAdmin中我们可以添加批量操作,比如“批量标记为已发货”。在OrderAdmin类内部添加:
actions=['mark_as_shipped']def mark_as_shipped(self, request, queryset): updated=queryset.filter(status=1).update(status=2)# 待发货 -> 待收货self.message_user(request, f'已成功将 {updated} 个订单标记为已发货。')mark_as_shipped.short_description='批量标记为已发货'刷新订单列表页,在动作下拉框里就能看到“批量标记为已发货”了。
3.4 自定义 Admin 模板标题
编辑django_ecommerce/urls.py(临时测试),也可以在settings.py中通过ADMIN_SITE_HEADER等变量修改站点标题。在settings.py末尾加上:
ADMIN_SITE_HEADER="电商后台管理系统"ADMIN_SITE_TITLE="电商管理"ADMIN_INDEX_TITLE="欢迎使用电商管理后台"刷新 Admin,顶部的“Django 管理”就变成了“电商后台管理系统”。
四、数据初始化——给空表“填饱肚子”
有了后台,理论上我们可以逐条手动录入商品,但那太慢了。我们需要一种自动化的方式来批量导入基础数据。Django 提供了几种方案:fixture、自定义管理命令、数据迁移。推荐使用自定义管理命令,因为它最灵活,而且可以调用项目的完整代码。
4.1 创建管理命令目录结构
在apps/products下新建以下目录和文件:
apps/products/ └── management/ ├── __init__.py └── commands/ ├── __init__.py └── init_product_data.py确保每个__init__.py都是空文件(告诉 Python 这是一个包)。
4.2 编写初始化脚本
编辑apps/products/management/commands/init_product_data.py:
from django.core.management.baseimportBaseCommand from products.modelsimportCategory, SPU, SKU, ProductImage from decimalimportDecimal class Command(BaseCommand):help='初始化商品基础数据'def handle(self, *args, **kwargs): self.stdout.write('开始初始化数据...')# 1. 创建分类electronics=Category.objects.create(name='电子产品',level=1,sort=1)phone=Category.objects.create(name='手机',parent=electronics,level=2,sort=1)computer=Category.objects.create(name='电脑',parent=electronics,level=2,sort=2)clothing=Category.objects.create(name='服装',level=1,sort=2)men=Category.objects.create(name='男装',parent=clothing,level=2,sort=1)women=Category.objects.create(name='女装',parent=clothing,level=2,sort=2)self.stdout.write(self.style.SUCCESS('分类创建完成'))# 2. 创建 SPUspu_iphone=SPU.objects.create(name='iPhone 15',brand='Apple',desc='Apple 最新款智能手机',category=phone)spu_macbook=SPU.objects.create(name='MacBook Pro 16',brand='Apple',desc='专业级笔记本电脑',category=computer)spu_tshirt=SPU.objects.create(name='纯棉 T 恤',brand='Uniqlo',desc='舒适百搭的日常 T 恤',category=men)self.stdout.write(self.style.SUCCESS('SPU 创建完成'))# 3. 创建 SKUsku1=SKU.objects.create(spu=spu_iphone,name='iPhone 15 128GB 午夜色',specs={'颜色':'午夜色','存储':'128GB'},price=Decimal('5999.00'),cost_price=Decimal('4500.00'),stock=100,sales=0,is_active=True)sku2=SKU.objects.create(spu=spu_iphone,name='iPhone 15 256GB 午夜色',specs={'颜色':'午夜色','存储':'256GB'},price=Decimal('6999.00'),cost_price=Decimal('5500.00'),stock=50,sales=0,is_active=True)sku3=SKU.objects.create(spu=spu_macbook,name='MacBook Pro 16 M3 Pro 512GB',specs={'芯片':'M3 Pro','存储':'512GB'},price=Decimal('19999.00'),cost_price=Decimal('16000.00'),stock=30,sales=0,is_active=True)sku4=SKU.objects.create(spu=spu_tshirt,name='纯棉 T 恤 白色 M',specs={'颜色':'白色','尺码':'M'},price=Decimal('99.00'),cost_price=Decimal('50.00'),stock=200,sales=0,is_active=True)sku5=SKU.objects.create(spu=spu_tshirt,name='纯棉 T 恤 黑色 L',specs={'颜色':'黑色','尺码':'L'},price=Decimal('99.00'),cost_price=Decimal('50.00'),stock=150,sales=0,is_active=True)self.stdout.write(self.style.SUCCESS('SKU 创建完成'))# 4. 给部分 SKU 创建主图(先不传实际图片,只演示占位)# 实际开发中可配合 File 对象或图片 URL 导入self.stdout.write(self.style.SUCCESS('初始化完成!'))4.3 执行初始化命令
python manage.py init_product_data控制台输出:
开始初始化数据... 分类创建完成 SPU 创建完成 SKU 创建完成 初始化完成!现在我们回到 Admin 后台,点击“商品分类”、“SPU”、“SKU”,就能看到刚刚灌入的数据了。运营人员可以在后台进一步完善图片、修改库存和价格。
五、补充:fixture 方式快速导入/导出数据
有时你需要把数据库中的数据导出为 JSON 文件,备份或共享。Django 的 fixture 功能可以胜任。
导出数据:
python manage.py dumpdata products--indent2>products_fixture.json导入数据(另一环境或清库后恢复):
python manage.py loaddata products_fixture.jsonfixture 适用于表结构不变的数据备份,但逻辑复杂的初始化还是推荐自定义管理命令。
六、总结与下集预告
今天我们让 Django Admin 真正为电商项目服务了:
创建了超级管理员,成功登录后台;
将所有自定义模型注册到 Admin,并通过内联、列表编辑、自定义操作等高级特性大幅提升了后台的可用性;
编写了自定义管理命令,一键初始化了商品分类、SPU、SKU 的基础数据;
了解了 fixture 的导出和导入,为后续数据备份打下基础。
至此,我们的项目骨架、数据库、后台管理、初始数据已经全部就位,接下来就是面向用户的功能开发了。第 5 天,我将带你做项目基础配置的收尾工作:整合 Bootstrap 5 静态文件、配置模板路径、处理媒体文件上传,打造一个漂亮统一的前端基础。别忘了追更!
想了解更多还其它平台搜索「IT策士」,一起升级 IT 思维 !
*本文为《Django 从 0 到 1 打造完整电商平台》系列第 4 篇,作者:IT策士,未经授权禁止转载。
*