ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于Python和Django的售楼管理系统设计与实现:从数据库到并发控制

基于Python和Django的售楼管理系统设计与实现:从数据库到并发控制 毕设季又到了每年这个时候总能在各种群里看到同一批问题有没有现成的管理系统源码Python毕设做什么题目好过我接触过的计算机类毕业生里十个有七个在做管理系统只不过大部分人的选题还停留在图书管理、学生信息、宿舍分配这些几年前就被写烂的场景上。今天要聊的这套基于Python的售楼管理系统属于看上去朴素、实际够用、答辩好讲的典型——售楼业务的流程复杂度远高于普通的增删改查天然自带房源状态流转、客户跟进、交易合同、回款统计这些业务概念无论是做毕设源码参考还是打算二次开发成一个像样的个人项目它都值得你花点时间认真拆一遍。这篇文章不是给你贴一大堆代码就完事我会把系统从功能拆解、数据库设计到核心业务逻辑的实现思路全捋一遍最后再聊答辩和改造的事。哪怕你目前Python水平停留在能写函数、刚分清类和对象只要照着这个思路走一遍这套售楼管理系统的来龙去脉你就能讲得明明白白。1. 毕设选题售楼管理系统的含金量藏在业务复杂度里1.1 为什么售楼比图书管理更能撑起一篇毕设先明确一个大多数人没想透的问题毕设管理系统老师说到底是看你的建模能力和工程逻辑不是看你功能列表有多长。图书管理系统的业务闭着眼睛都能想全——读者、图书、借阅记录三条表就结束了哪怕你把界面做得再花哨答辩时三两句话就能被问穿。售楼管理系统不一样它的业务链路天然分层楼盘 - 楼栋 - 单元 - 房源 - 意向客户 - 看房预约 - 成交合同 - 回款记录每一层都有自己的状态和规则。举个例子一个房源不是存在和不存在两种状态而是要经历待售 - 预定 - 已售的完整生命周期中间还可以有保留房源这种售楼处特有的操作一个客户也不是简单存个姓名电话而是要从意向登记 - 带看跟进 - 认购 - 签约一步步推进。这些真实业务场景的存在意味着你的数据表之间不再是松散的关联而是被一条条业务规则拧在一起。对毕设来说这就是最好的得分点。1.2 Python技术栈的选择逻辑Django为主Flask为辅既然是Python项目框架上无非是两个选择Django还是Flask。我的建议很直接毕业设计优先选Django。原因不是Flask不好而是Django把太多你在毕设里必需的东西都内置好了。用户认证Django自带的User模型、登录状态、session管理几行配置就能用能省掉你实现注册登录的一大半功夫。Admin后台Django Admin对毕设来说简直是救命稻草。前期调试数据、给老师演示后台管理功能甚至是在你前端页面没做完时应急展示它都能顶上。ORM和迁移python manage.py makemigrations 和 migrate 两条命令就能建表不需要你手写繁琐的SQL建表语句对不熟悉数据库的同学非常友好。Flask胜在轻量适合展示个人风格但流量和权限这块都得自己额外配Flask-Login之类的扩展工作量会比想象中大。除非你对Flask已经很熟否则不建议在毕设阶段给自己加这个负担。环境上建议Python 3.10 Django 4.x MySQL 8.0的组合这套搭配的坑最少网上能搜到的参考也最多。2. 功能拆解三类角色、一条销售主链路、六个核心模块2.1 用户角色决定了权限设计的边界售楼管理系统不是单机小工具它的核心价值在于不同身份的人在同一套房屋数据上协作。我建议你至少设计三种角色这样权限控制才有东西可写角色职责范围核心权限系统管理员维护基础数据、账号管理、数据总览楼盘和房源的新增上下架、用户管理、全部数据查看销售人员日常业务操作客户登记、预约看房、跟进记录、房源预定与成交销售经理监督和统计查看全团队销售报表、审核退房/退款、管理折扣这里有一个很实在的设计点不要用is_superuser一刀切管理员也不要让每个角色都写死一堆if else。Django里面用Group加Permission来做权限控制是标准做法后边我会讲到具体怎么落。角色边界再稍微模糊一点都没关系答辩时你能说清楚谁可以用什么功能就够了。2.2 核心模块从楼盘维护到成交统计在功能列表设计上我建议围绕一条售楼处业务流程串起来而不是罗列一堆看似高大上的功能。这条主线是楼盘建盘 - 房源入库 - 客户登记 - 预约看房 - 认购预定 - 合同成交 - 数据统计。顺着这条主线核心模块就那么几个楼盘与房源管理维护楼盘名称、位置、容积率、绿化率、开盘时间维护楼栋、单元、楼层、户型、面积、单价和朝向。这是业务的基础数据层。客户管理登记意向客户信息记录客户来源自然来访、中介推荐、老带新等每次跟进都留一条跟进历史不要只有一个最新状态。这个模块对答辩来说很重要因为它体现了你对过程数据的理解。预约与带看管理给客户约看房时间记录置业顾问带领看了哪些房源客户对房源的反馈。成交与合同管理选定房源 - 锁定房源状态 - 生成销售订单和合同信息包括成交总价、首付、贷款方式、签约日期。这里要处理一个最容易出问题的地方同一套房源不能被两个人同时认购后面我会展开讲。数据统计与报表用图表展示不同楼盘的销售情况、成交面积分布、月度销售额走势、销售员业绩排行。这个模块是你答辩PPT的素材来源不能没有。你仔细感受一下这套功能列表里没有一个是凑数的。每个模块都有明确的业务含义这在答辩时直接决定了老师觉得你是在做系统还是在抄代码。3. 数据库建模房源状态机与订单唯一性的底层设计3.1 核心表结构敢在答辩现场画ER图的那种数据库设计是管理系统类毕设的灵魂也是答辩老师最爱深挖的部分。我先把这套系统里最核心的几张表摆出来再解释几个关键的设计决策。-- 楼盘表 CREATE TABLE building ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) NOT NULL COMMENT 楼盘名称, location VARCHAR(128) NOT NULL COMMENT 地理位置, developer VARCHAR(64) COMMENT 开发商, open_date DATE COMMENT 开盘日期, area_total DECIMAL(10,2) COMMENT 总建筑面积, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 楼栋表归属于楼盘 CREATE TABLE building_unit ( id INT PRIMARY KEY AUTO_INCREMENT, building_id INT NOT NULL COMMENT 所属楼盘, unit_name VARCHAR(32) NOT NULL COMMENT 楼栋号, layer_count INT COMMENT 总层数, FOREIGN KEY (building_id) REFERENCES building(id) ); -- 房源表具体到每一套房子 CREATE TABLE house ( id INT PRIMARY KEY AUTO_INCREMENT, unit_id INT NOT NULL COMMENT 所属楼栋, room_no VARCHAR(16) NOT NULL COMMENT 房号, floor_number INT COMMENT 所在楼层, area DECIMAL(6,2) NOT NULL COMMENT 建筑面积, unit_price DECIMAL(10,2) NOT NULL COMMENT 单价, total_price DECIMAL(14,2) NOT NULL COMMENT 总价, decoration VARCHAR(16) COMMENT 装修情况, house_type VARCHAR(16) COMMENT 户型如三室两厅, status TINYINT DEFAULT 0 COMMENT 房源状态 0待售 1预定 2已售 3保留, UNIQUE KEY uk_unit_room (unit_id, room_no) );这几张表是基础层接下来是客户和交易层的表-- 客户表 CREATE TABLE customer ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(32) NOT NULL, phone VARCHAR(20) NOT NULL, id_card VARCHAR(18) COMMENT 身份证号合同需要, source VARCHAR(16) COMMENT 客户来源, demand TEXT COMMENT 购房需求描述, level INT DEFAULT 0 COMMENT 意向程度 0低 1中 2高, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 预约看房表 CREATE TABLE visit_appointment ( id INT PRIMARY KEY AUTO_INCREMENT, customer_id INT NOT NULL, house_id INT NOT NULL, visit_date DATETIME NOT NULL, salesperson VARCHAR(32) COMMENT 接待销售, feedback TEXT COMMENT 客户反馈, status TINYINT DEFAULT 0 COMMENT 0待看房 1已到访 2已取消, FOREIGN KEY (customer_id) REFERENCES customer(id), FOREIGN KEY (house_id) REFERENCES house(id) ); -- 成交订单表 CREATE TABLE sale_order ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE COMMENT 订单编号, customer_id INT NOT NULL, house_id INT NOT NULL UNIQUE COMMENT 每套房源只能出现在一个订单里, salesperson VARCHAR(32) NOT NULL COMMENT 成交销售, deal_price DECIMAL(14,2) NOT NULL COMMENT 实际成交价, down_payment DECIMAL(14,2) COMMENT 首付款, loan_amount DECIMAL(14,2) COMMENT 贷款金额, order_status TINYINT DEFAULT 0 COMMENT 0认购 1签约 2已退款, sign_date DATE COMMENT 签约日期, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (customer_id) REFERENCES customer(id), FOREIGN KEY (house_id) REFERENCES house(id) );3.2 三个设计决策背后的为什么第一house表里的status字段为什么不直接用字符串存待售已售而是用TINYINT加注释这纯粹是从规范和查询效率考虑的。整数类型做索引和等值匹配都比字符串快Django模型里用IntegerField加choices就能映射成可读文案。最重要的是这个字段是整套系统状态机的核心我建议你在模型层里一次性把状态转移规则定清楚比如从待售只能到预定或保留不能直接跳已售。这套规则写在哪可以在Django的model的clean方法里也可以在业务视图层做校验不管放哪意识必须有。第二sale_order表里的house_id为什么要加UNIQUE约束这是防住一房多卖的底层保险。业务代码可能因为并发请求出现漏洞但数据库层面的唯一约束能保证同一个房源永远只出现在一张有效订单里。这条约束在答辩时非常加分因为它证明你考虑了数据一致性问题而不是只会在页面上弹个alert提示。第三客户和房源的关系通过中间表visit_appointment关联。这是多对多关系的标准建模法。一个客户可以看多套房一套房也可以被多个客户看而每一次看房行为本身又有自己的属性时间、反馈、状态所以不能简单用客户表里加个看了哪套房字段来解决必须拆出独立的关系表。能把这个逻辑讲清楚你已经超过了绝大多数照抄代码的同学。4. 后端核心实现Django下认证、权限、事务与并发控制4.1 项目初始化与环境准备这一节我们直接落到代码层面。假设你已经装好了Python 3.10和MySQL 8.0接下来从零把后端框架搭起来。我用的是Django 4.2这版本比较稳定Django 5.x其实也可以但某些第三方库的兼容性要额外确认毕业设计没必要追新。# 创建虚拟环境避免污染全局Python python -m venv venv # 激活虚拟环境Windows执行 venv\Scripts\activateLinux/Mac执行 source venv/bin/activate venv\Scripts\activate # 安装Django和数据库驱动 pip install django4.2 mysqlclient # 如果你的MySQL版本比较新mysqlclient装不上可以换用pymysql # 用pymysql的话需要在项目__init__.py里加两行 # import pymysql # pymysql.install_as_MySQLdb() # 创建项目和一个核心应用 django-admin startproject sales_system cd sales_system python manage.py startapp houses python manage.py startapp customers python manage.py startapp orders在settings.py里把应用注册进去同时配置数据库连接INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, houses, customers, orders, ] DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: sales_db, USER: root, PASSWORD: 你自己的密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: { charset: utf8mb4, }, } }这里有个常见的坑MySQL 8.0默认的认证插件是caching_sha2_passwordmysqlclient 老版本可能连不上。建议在MySQL里创建专用账户时直接指定认证方式避免折腾CREATE USER sales_userlocalhost IDENTIFIED WITH mysql_native_password BY yourpassword; GRANT ALL PRIVILEGES ON sales_db.* TO sales_userlocalhost;4.2 用Django Group把三种角色的权限理清楚Django自带的auth应用里就有完善的权限框架不需要自己造轮子。做法分三步第一步创建角色的Group。你可以在Django shell或者Admin后台里手动创建三个分组也可以在数据迁移脚本里自动初始化。我推荐用后一种方式因为这样在新环境部署时不用手动重复配置# houses/management/commands/init_groups.py from django.core.management.base import BaseCommand from django.contrib.auth.models import Group, Permission from django.contrib.contenttypes.models import ContentType from django.apps import apps class Command(BaseCommand): help 初始化角色分组和权限 def handle(self, *args, **options): # 拿出几个核心模型的内容类型 house_ct ContentType.objects.get_for_model(apps.get_model(houses, House)) customer_ct ContentType.objects.get_for_model(apps.get_model(customers, Customer)) order_ct ContentType.objects.get_for_model(apps.get_model(orders, SaleOrder)) sales_group, _ Group.objects.get_or_create(name销售人员) manager_group, _ Group.objects.get_or_create(name销售经理) admin_group, _ Group.objects.get_or_create(name系统管理员) # 销售人员可以新增和修改客户可以预定房源但删除权限不留 sales_group.permissions.add( Permission.objects.get(codenameadd_customer, content_typecustomer_ct), Permission.objects.get(codenamechange_customer, content_typecustomer_ct), Permission.objects.get(codenameview_customer, content_typecustomer_ct), ) # 系统管理员拥有所有权限 admin_group.permissions.set(Permission.objects.all())执行这条命令后三个角色就初始化好了python manage.py init_groups第二步把创建用户和分配角色封装到一个函数里。这样不管是Admin后台手动建号还是将来做注册页面都能调同一个逻辑def create_user_with_role(username, password, role_name): user User.objects.create_user(usernameusername, passwordpassword) group Group.objects.get(namerole_name) user.groups.add(group) return user第三步在视图中用装饰器或混合类检查权限。比如销售人员能提交认购申请但不能看到全系统的财务汇总可以用Django自带的permission_requiredfrom django.contrib.auth.decorators import login_required, permission_required login_required permission_required(customers.add_customer, raise_exceptionTrue) def customer_create(request): # 新增客户逻辑 pass不过说实话毕业设计里把页面权限做到用装饰器控制每个视图的颗粒度就够了实在不想写这么多装饰器的话在系统管理员的菜单模板上按{% if perms.xxx %}做按钮级的隐藏也是可接受的降级方案。答辩时你能说清楚销售人员看不到管理菜单管理员不能操作业务单据这个核心区别就行。4.3 房源状态流转写一套规则杜绝乱改状态房源状态是这个系统里最容易出逻辑漏洞的地方。最原始的做法是直接在视图里写死状态修改的逻辑但更规范的做法是把状态流转规则集中到一个独立的文件里。这个设计答辩时可以说我是用状态机模式来管理房源状态的。# houses/services.py class HouseStatus: AVAILABLE 0 # 待售 RESERVED 1 # 预定 SOLD 2 # 已售 HELD 3 # 保留 # 定义允许的状态流转key是当前状态value是允许流转到的状态集合 TRANSITIONS { HouseStatus.AVAILABLE: {HouseStatus.RESERVED, HouseStatus.HELD}, HouseStatus.RESERVED: {HouseStatus.SOLD, HouseStatus.AVAILABLE}, # 预定可以转已售也可以取消回到待售 HouseStatus.HELD: {HouseStatus.SOLD, HouseStatus.AVAILABLE}, # 保留房同样可以成交或释放 HouseStatus.SOLD: set(), # 已售房源不可再修改状态 } def change_house_status(house, new_status): if new_status not in TRANSITIONS.get(house.status, set()): raise ValueError(f房源状态不能从当前状态切换到目标状态) house.status new_status house.save() # 这里可以同时写一条房源状态变更日志方便审计 return house有一个细节值得你注意任何状态变更首先要在服务层校验规则然后再落库。视图里所有修改房源状态的操作都必须调这个函数而不是直接对house.status赋值然后save()。一旦你允许业务代码绕过规则过两天你就会发现数据变成了一锅粥——既给不了老师一个好的解释也暴露了工程经验的短板。4.4 并发下单同一个房源不能卖两次这是整套系统里技术含量最高的一个点也是答辩中老师最容易眼睛一亮的地方。场景是这样的房源的户型、楼层、价格都很好两个客户几乎同时下了认购意向如果代码没有做并发控制两个请求都检查到房源状态是待售然后都执行了更新成了已售那就出大问题了。解决思路有两个层次第一个层次叫乐观锁。在house表里加一个version字段每次更新的时候带上版本号updated House.objects.filter( idhouse_id, statusHouseStatus.AVAILABLE, versioncurrent_version ).update( statusHouseStatus.RESERVED, versioncurrent_version 1 ) if updated 0: # 说明房源已经被人抢占了返回友好提示 return JsonResponse({code: 1, msg: 该房源刚刚被预定请刷新后重试})第二个层次叫悲观锁用Django的select_for_update加事务。这也是我更推荐的做法因为它的语义非常直观——在检查房源状态之前先把这行记录锁住其他事务只能等这个事务结束再操作from django.db import transaction transaction.atomic def reserve_house(request, house_id): # 加行锁读取房源直到事务结束才释放 house House.objects.select_for_update().get(idhouse_id) if house.status ! HouseStatus.AVAILABLE: return JsonResponse({code: 1, msg: 该房源当前不可预定}) # 创建订单、更新客户状态等业务操作 house.status HouseStatus.RESERVED house.save() SaleOrder.objects.create( househouse, customer_idrequest.POST[customer_id], deal_pricehouse.total_price, order_status0, # ... ) return JsonResponse({code: 0, msg: 预定成功})注意代码里的顺序很重要先锁行后检查状态再修改最后创建订单。很多人写反了先查询状态再锁行这样锁的意义就没了。用select_for_update的时候还需要保证操作在一个事务里所以函数用transaction.atomic包起来缺一不可。数据库层面那个UNIQUE约束sale_order.house_id就是你防并发失守之后的最后一道保险。万一真的有脏数据进来了MySQL会直接报错而不是静默双写。这三层防护数据库唯一约束 状态机规则 锁机制分别从不同层面保证了一房一单的绝对正确性。这个设计足够你在答辩时讲五分钟不冷场。5. 前端页面怎么用Django Template加Bootstrap做得像个正经系统5.1 页面框架与布局设计后端逻辑再完整页面做得太简陋也容易在展示环节吃亏。但毕设阶段没必要上Vue、React这种前后端分离的大工程——除非已经工作过否则这会让你的工作量翻倍而且答辩老师不一定认可。我更推荐Django Template Bootstrap 5 jQuery这套组合理由有三点一是Bootstrap能让你不用写CSS就有还不错的视觉效果二是Django Template的模板继承机制能让每个页面只写改动的部分效率极高三是jQuery的Ajax足够应付这类系统90%的交互场景不需要引入复杂的前端工程化工具链。页面整体结构你可以这样设计base.html包含顶部的系统标题栏、左侧菜单栏、右侧内容区域的骨架用Bootstrap的栅格和折叠菜单完成。登录页单独设计不做左侧菜单登录之后跳转到首页仪表盘。首页仪表盘展示核心统计卡片比如总房源数、待售房源数、今日预约数、本月成交额下方可以放一个最近成交记录表格。各业务模块页面房源管理、客户管理、订单管理等表格展示数据点行尾的按钮进入详情或编辑。一个建议左侧菜单用Django模板的RequestContext变量来判断当前用户权限这样可以实现管理员看到系统设置菜单销售人员看不到的效果。比如{% if perms.houses.add_house %} lia href{% url house_create %}新增楼盘/a/li {% endif %}5.2 从零写一个房源管理页面以房源列表页为例思路是这样的视图函数从数据库取数据模板渲染成表格支持按楼栋筛选和按状态筛选行尾的操作按钮根据状态动态显示。视图部分from django.shortcuts import render from django.core.paginator import Paginator from .models import House def house_list(request): houses House.objects.select_related(unit__building).order_by(unit__building__id, room_no) # 处理查询参数 status request.GET.get(status) if status not in (None, , all): houses houses.filter(statusstatus) keyword request.GET.get(keyword) if keyword: houses houses.filter(room_no__icontainskeyword) paginator Paginator(houses, 10) page_number request.GET.get(page) page_obj paginator.get_page(page_number) context { page_obj: page_obj, current_status: status, keyword: keyword, } return render(request, houses/house_list.html, context)模板部分表格行里的状态根据数值显示不同颜色的badge{% for house in page_obj %} tr td{{ house.unit.building.name}}/td td{{ house.unit.unit_name }}栋/td td{{ house.room_no }}/td td{{ house.area }} 平/td td{{ house.unit_price }}/平/td td {% if house.status 0 %} span classbadge bg-success待售/span {% elif house.status 1 %} span classbadge bg-warning预定/span {% elif house.status 2 %} span classbadge bg-secondary已售/span {% else %} span classbadge bg-info保留/span {% endif %} /td td a href{% url house_detail house.id %} classbtn btn-sm btn-outline-primary详情/a {% if house.status 0 %} a href{% url house_reserve house.id %} classbtn btn-sm btn-outline-success预定/a {% endif %} /td /tr {% endfor %}这个是毕设系统的典型交互模式列表 筛选 分页 状态标记 操作按钮。把这些页面加起来整个系统大概需要十来个页面模板工作量可控效果也不会差。为了直观展示销售数据可以在统计页引入ECharts的CDN用两个折线图或柱状图展示月度成交趋势和销售业绩排行后端把聚合好的JSON数据通过Ajax传过去就行。6. 拿到这套源码之后必须动手改掉的几个地方6.1 直接换皮交毕设风险远比你想象的大我知道不少人是冲着毕设源码这四个字来的拿到代码的第一反应可能是赶紧把数据库跑起来再把个人信息改一改就算完成。但作为过来人我必须给你一个正经建议源码可以拿但绝对不能直接提交。因为答辩环节里老师会随机提问如果代码不是你亲手的产物你甚至连自己项目里的建表顺序都说不清楚。与其赌运气不如花两三天时间把代码从头到尾读一遍把里面跟自己习惯不符的地方改一改。具体可以从这几个地方动手把项目里的版权信息、作者注释、甚至数据库名全部换成自己的风格这不是什么见不得人的事独立完成一个项目本来就包括环境搭建。重新设计数据库的初始数据。默认数据太假比如张三李四这种明显是演示数据的客户答辩展示时观感很差。自己造一批带真实感的楼盘数据比如滨江·云著城东学府里每个楼盘的户型、面积、单价要有逻辑一致性。页面标题、Logo、系统名称要换成你自己的。系统还叫售楼管理系统这种通用名倒还好但如果默认标题栏写着别人的个人信息或机构名称那大概率会被追问。6.2 推荐加入一两个自己的功能模块想给老师一个印象分的高点最好的办法是在源码基础上加一个小功能模块。不用太复杂但一定是这套系统里没有的、且和售楼业务自洽的。我提供几个思路供你参考房源收藏夹客户在浏览房源时点收藏之后在客户详情页能看到这个客户收藏过的房源列表。这个功能对销售把握客户意向很有帮助实现起来只要一张多对多关联表。销售周报自动生成每周日晚上自动统计每个销售员的带看次数、新增客户数、成交金额生成一张汇总周报页面。逾期回款提醒订单里如果有分期付款或贷款进度字段对超过约定日期还没回款的订单在首页醒目位置用红字提醒。房源VR看房链接相当于给每个房源存一个外部链接字段。虽然功能本身很简单但你能在答辩时讲出线上看房是售楼处数字化转型的一个重要需求这格局就拉开了。这些模块的实现难度都不大关键在于它能把别人的源码变成你的作品。哪怕只是加一个自定义字段再加一个筛选条件在答辩时你也能理直气壮地说这一块是我自己设计的。7. 答辩现场演示顺序与高频问题7.1 演示顺序要讲业务故事而不是念菜单答辩时的系统演示环节我见过太多人一上台就从用户管理开始点把自己做成了软件说明书朗读机。正确的演示方式应该是按业务场景来讲故事让老师跟着你走一遍完整的售楼流程。推荐这个顺序登录系统一句话介绍当前登录的是管理员还是销售人员。先进楼盘管理建一个新楼盘再到房源管理里给这个楼盘生成楼栋和户型。这一步展示了系统基础数据的维护能力。切到客户管理登记一个新客户给这个客户建一条预约看房记录把客户意向等级调高。回到房源列表找到一套待售房源走一遍预定流程。如果之前做了并发控制演示这里可以提一句后台做了防重保护。把房源状态改成已售生成一笔订单然后去统计报表里看看销售额是否及时更新。最后展示权限用销售人员账号登录发现系统设置菜单不可见从而引出你们的权限设计。掌握这个顺序你对系统的表达就有节奏感了。比起干巴巴地介绍这个页面实现了增删改查这明显更像一个产品经理在做业务路演。7.2 高频问题清单和回答思路答辩老师一般不会故意为难你但那些关于为什么怎么保证的问题你要能接得住。我把最高频的几个问题整理一下问为什么选择Python而不是Java答Python语法简洁开发效率高Django框架内置了大量开箱即用的组件让我能把精力集中在业务流程的设计上。另外Python在数据处理方面有天然优势后续做销售数据统计分析时可以直接利用pandas等库扩展功能。这个问题没有标准答案关键是要说得真诚。问你的数据库表之间是什么关系答楼盘和楼栋是一对多楼栋和房源是一对多客户和房源是多对多通过预约看房表关联订单和客户、房源都是一对一。然后拿出ER图来按链路讲一遍。ER图你一定要提前准备好放在PPT里最好是用专业工具画的。问同一个房源如果被两个人同时预定怎么办答三层防护。数据库层面sale_order表的house_id有唯一约束服务层用select_for_update加行锁确保同一时刻只有一个事务能改房源状态状态机上又规定了只有待售状态的房源才能流转到预定已售状态的房源不允许再流转。这样就保证了房源不会被重复销售。问你的系统安全性如何保证答用户密码使用Django内置的PBKDF2算法加密存储所有ORM查询都是参数化查询从机制上杜绝了SQL注入每个表单都有CSRF Token校验权限上使用基于角色的访问控制未授权用户即使在URL输入路径也无法访问对应页面。问统计报表的数据是怎么来的答基础的聚合数据直接用Django ORM里的Count、Sum等聚合函数从订单表按月份分组统计成交总价。如果将来数据量大可以考虑提前在数据库建视图或者用Redis缓存热点查询结果。最后这半句是加分句点到为止就行。还有一个细节容易被忽略提前把系统跑在一台干净的机器上检查所有依赖是不是已经装好。每年都有学生答辩时现场装环境装到一半老师已经失去耐心了。把这些隐蔽的问题提前处理掉你的毕设答辩就成功了一大半。最后再絮叨一句实际操作层面的体会这套系统虽然挂的是毕设源码的名头但它的骨架足够让你延伸出很多玩法。比如给房源加上图片字段和户型图展示客户详情页和服务端做消息通知甚至把销售数据用爬虫抓取周边竞品楼盘价格做个对比分析。这些扩展方向将来写到简历的项目经验里每一句都能变成面试官感兴趣的话题。先把基础功能和业务逻辑吃透剩下的事情就是一层一层往上加想法。
返回列表