ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Django实战开发公园定位系统:从地图导航到路线规划完整指南

Django实战开发公园定位系统:从地图导航到路线规划完整指南 做毕设选Django十个里有九个认准一个理儿生态全、坑少、文档厚卡住的时候搜一下到处都是答案。公园定位系统这个题近两年在我手上过了不下十遍算是在位置服务类毕设里比较有代表性的一个。它不像纯管理后台那样一眼看到头也不像深度学习项目那样一上来就把人劝退正好卡在“做得出来”和“拿得出手”之间的位置。这个系统说白了就是给公园做一个轻量级的导览和定位平台游客打开网页能看到整个园区的地图、每个景点在哪、自己大概在哪个位置、从当前位置怎么走到想去的景点管理员在后台维护景点信息、分类和公告。基于Django来写原因很简单——ORM操作数据库省心自带的Admin后台直接省掉一大半管理界面开发量用户认证、CSRF防护、密码哈希这些安全机制也都是现成的。这篇文章我会从需求拆解、技术选型、数据库设计、核心功能实现到调试部署一路讲下去末尾还整理了近两年学生问得最多的问题和对应的排查思路适合正在做Django项目但没想清楚整体架构的新手参考。1. 系统定位与需求梳理1.1 公园定位系统的核心价值很多人一听到“定位系统”就联想到导航软件、GPS卫星、实时轨迹觉得这题特别难。实际上公园定位系统的核心从来不是高精度的定位算法而是“位置 信息服务”的组合。公园场景下的游客痛点很真实进了一个面积上百亩的公园知道景点名字但不知道往哪走走到一个岔路口不知道自己在什么位置、附近有什么想找洗手间、找出口、找便利店全靠看纸质地图效率极低。公园管理方想把游线推荐、限流提示、活动公告推给游客也要有个抓手。所以这个系统的价值是给游客一个“打开即用”的网页端数字导览同时给管理方一个可维护、可扩展的后台。定位在这里的作用不是厘米级精确导航而是通过浏览器获取用户当前位置告诉游客“你在哪、附近有什么、怎么走”这才是对“公园定位”这四个字最务实的理解。把这个定位想清楚后面做功能规划的时候就不会跑偏。1.2 功能拆解最小的可用闭环功能设计上我建议围绕一个“最小闭环”来做游客打开地图 → 看到景点 → 看到自己位置 → 选择目的地 → 看到路线 → 到达后再逛逛旁边景点。六个环节走通了系统的价值就完整了。按用户角色拆下来大致如下游客端公园地图展示、景点列表与详情、实时定位、路线规划、景点收藏与浏览记录。管理端景点信息增删改查、景点分类管理、图片上传、公告发布。公共模块用户注册、登录、退出、修改密码。有同学会问要不要做实时GPS轨迹、多人互动、AR导航这些都是加分项不是必选题。如果一个项目把精力全花在花哨功能上结果页面简陋、数据库设计混乱答辩的时候反而容易露怯。我一般建议先把最小闭环做到位在文档里把“后续扩展方向”写清楚这比堆功能更有说服力。1.3 为什么选择Django做后端这个问题不只是技术选型更是答辩时一定会问的高频问题。Django的优势体现在三个层面。第一是开发效率。它自带ORM你不用写一行SQL就能完成大部分建表和查询操作自带Admin后台景点表一注册后台就能直接增删改查管理端工作量直接砍掉一半自带用户认证体系注册、登录、会话管理都有现成方案。第二是安全性。Django默认防御SQL注入、XSS攻击、CSRF攻击密码使用PBKDF2加盐哈希存储这对一个要展示给答辩评委看的项目来说非常重要。当你被问到“你的系统安全吗”的时候能从这三个方面答出来比空喊技术先进靠谱得多。第三是生态和资料。Django是Python Web开发里资料最完善、社区最活跃的框架之一新手遇到问题能查到的解决方案多远程调试的时候也更好定位问题。另外Python这门语言本身门槛低对毕设周期紧张的学生来说更友好。2. 技术架构与工程结构2.1 技术栈选型与对比根据上面梳理的需求我在实际带项目时给出的推荐技术栈是这样的后端框架选Django 3.x或4.x长期支持版本前端用Django模板引擎加Bootstrap 5做UI布局地图展示用Leaflet.js加载OpenStreetMap瓦片数据库本地用SQLite、部署到服务器换MySQL开发调试工具用Django Debug Toolbar远程调试用VS Code Remote SSH。选Leaflet而不是高德或百度地图核心原因是规范教育之外还牵扯授权问题。高德、百度都要求申请开发者Key而且Web服务有调用配额和商用授权限制虽然个人学习申请很宽松但在毕设答辩场景里一旦Key配置不对页面就是空白。而Leaflet加载OpenStreetMap瓦片不需要Key完全免费代码清晰可控对教学演示和源码讲解都更友好。数据库方面SQLite和MySQL的选择我单独列了一张表对比项SQLiteMySQL部署复杂度零配置Django默认支持需要安装服务、创建数据库适用场景本地开发、演示、数据量小服务器部署、多人访问并发能力弱写并发锁竞争明显强适合多请求场景迁移成本开发期用交付时可导出稳定后直接切换2.2 Django项目目录结构设计项目创建和app拆分有固定套路。命令我先放在这里# 创建虚拟环境并激活 python -m venv venv source venv/bin/activate # Windows下用 venv\Scripts\activate # 安装Django及依赖 pip install django # 创建项目与应用 django-admin startproject park_project cd park_project python manage.py startapp park_app python manage.py startapp user_app很多新手习惯把所有代码塞到一个app里这不是不行但项目规模一大就混乱。我习惯拆成两个apppark_app负责景点、地图、路线等业务user_app负责用户注册登录和收藏记录。这样职责边界清晰答辩的时候讲“模块化设计”也有实际依据。关键目录结构如下park_project/ ├── manage.py ├── park_project/ # 项目配置目录 │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── park_app/ # 公园业务应用 │ ├── models.py # 景点、分类模型 │ ├── views.py # 地图、定位、路线视图 │ ├── urls.py │ └── admin.py ├── user_app/ # 用户应用 │ ├── models.py # 收藏记录模型 │ ├── views.py # 注册、登录、个人中心 │ └── urls.py ├── static/ # 静态文件CSS、JS、图片 ├── media/ # 上传的景点图片 └── templates/ # 全站HTML模板2.3 settings.py关键配置settings.py是新手踩坑重灾区有几处必须说清楚。时区这一项如果项目只在本地跑把TIME_ZONE设为Asia/Shanghai、USE_TZ设为False存到数据库里的就是北京时间模板渲染和前端展示都不会出现“差8小时”的诡异问题。静态文件和媒体文件配置如下import os BASE_DIR os.path.dirname(os.path.dirname(os.path.abspath(__file__))) INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, park_app, user_app, ] # 静态文件目录 STATIC_URL /static/ STATICFILES_DIRS [os.path.join(BASE_DIR, static)] # 上传图片保存目录 MEDIA_URL /media/ MEDIA_ROOT os.path.join(BASE_DIR, media) # 语言与时区 LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_TZ False这里要特别提醒STATICFILES_DIRS这个配置。很多初学者建了static文件夹、放了CSS文件但忘记在settings.py里声明目录导致模板里的样式死活加载不出来页面长得跟纯文本似的。问题不大但排查起来很耽误时间。3. 核心功能模块实现3.1 地图加载与景点标注地图模块是整个系统最亮眼的部分也是很多学生动手最早、卡壳最多的部分。实现逻辑分成三层页面加载Leaflet并初始化底图从后端请求景点数据把每个景点的坐标和名称渲染成地图标记。后端返回景点数据的视图代码如下import json from django.http import JsonResponse from .models import ScenicSpot def get_spots(request): 返回所有景点坐标和名称用于地图标注 spots ScenicSpot.objects.all() data [] for spot in spots: data.append({ id: spot.id, name: spot.name, lng: float(spot.lng), lat: float(spot.lat), category: spot.category.name, description: spot.description[:50], image: spot.image.url if spot.image else , }) return JsonResponse({code: 0, data: data})前端页面用Leaflet渲染// 初始化地图中心点设为公园中心坐标 var map L.map(map).setView([31.2304, 121.4737], 16); // 加载OpenStreetMap瓦片 L.tileLayer(https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png, { maxZoom: 19, attribution: copy; OpenStreetMap contributors }).addTo(map); // 请求后端景点数据并添加标记 fetch(/park/api/spots/) .then(response response.json()) .then(result { result.data.forEach(spot { var marker L.marker([spot.lat, spot.lng]) .addTo(map) .bindPopup(b spot.name /bbr spot.description); }); });坐标格式这里有个容易让人懵的地方。Leaflet的setView和marker接收的经纬度顺序是“纬度在前、经度在后”但我们在Django模型里存的和前端JSON返回的都是lng、lat分开的字段。新手容易在初始化地图时直接把经纬度顺序写反表现出来就是地图定位到了别的城市。只要记住“Leaflet永远lat在前、lng在后JSON字段永远lng在前、lat在后”就不会乱了。3.2 用户定位与坐标上报用户定位在Web端用的是浏览器的Geolocation API代码很短// 获取用户当前位置 function getUserPosition() { if (!navigator.geolocation) { alert(当前浏览器不支持定位); return; } navigator.geolocation.getCurrentPosition( function (position) { var lat position.coords.latitude; var lng position.coords.longitude; // 在地图上添加用户位置标记 L.marker([lat, lng]).addTo(map) .bindPopup(当前定位).openPopup(); // 可选将定位数据发送到后端 fetch(/park/api/location/, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({lat: lat, lng: lng}) }); }, function (error) { console.error(定位失败:, error.message); }, {enableHighAccuracy: true, timeout: 5000, maximumAge: 0} ); }这个代码看起来简单实际调试的时候会碰到一个特别经典的坑浏览器安全策略限制。Geolocation API只在HTTPS协议或者localhost本地环境下才允许调用如果你用局域网IP比如192.168.1.101:8000去访问项目浏览器控制台会报一个permissions policy相关的错误定位根本不会触发。解决方式是在部署或者演示时准备好一个HTTPS地址或者退一步在游客端提供一个“手动选择位置”的交互让用户在地图上点击一个点作为当前位置。不能指望教室里的WiFi环境都能顺利通过浏览器定位有手动的兜底方案演示的时候才不至于手忙脚乱。3.3 园区路线规划的简化实现路线规划是这个系统里含金量最高、也最容易在答辩时被深挖的功能。公司里可以用高德的路径规划API但毕设项目不依赖外部API、自己实现一个可用算法更能体现对图论和Django视图的综合运用。建模思路是这样的把公园里的景点看作节点把景点之间的步行道路看作边边的权重是两点之间的估算步行距离。然后用经典的Dijkstra算法求最短路径。模型层面上需要新增一个“道路连接”的表记录哪两个景点之间可以直达class PathEdge(models.Model): start_spot models.ForeignKey(ScenicSpot, on_deletemodels.CASCADE, related_namestart_edges) end_spot models.ForeignKey(ScenicSpot, on_deletemodels.CASCADE, related_nameend_edges) distance models.FloatField(verbose_name步行距离(米)) class Meta: verbose_name 道路连接后端视图读图并用Dijkstra求路径import heapq def shortest_path(request): start_id request.GET.get(from) end_id request.GET.get(to) # 构建邻接表 graph {} edges PathEdge.objects.select_related(start_spot, end_spot).all() for edge in edges: graph.setdefault(edge.start_spot_id, []).append((edge.end_spot_id, edge.distance)) graph.setdefault(edge.end_spot_id, []).append((edge.start_spot_id, edge.distance)) # Dijkstra算法 dist {start_id: 0} prev {} heap [(0, start_id)] while heap: d, node heapq.heappop(heap) if node end_id: break for neighbor, weight in graph.get(node, []): new_dist d weight if new_dist dist.get(neighbor, float(inf)): dist[neighbor] new_dist prev[neighbor] node heapq.heappush(heap, (new_dist, neighbor)) # 回溯路径 path [] node end_id while node ! start_id: path.append(node) node prev[node] path.append(start_id) path.reverse() return JsonResponse({path: path, distance: dist.get(end_id)})前端拿到路径之后用Leaflet的polyline把路径节点连线画到地图上游客就能清楚地看到从当前位置到目的地应该怎么走。路线规划能做到这个程度在毕设里已经相当能打了。3.4 后台管理与数据维护Django Admin是这个项目不要白不要的红利。把模型注册到admin.py里后台管理界面就出来了from django.contrib import admin from .models import ScenicSpot, ScenicCategory, PathEdge admin.register(ScenicSpot) class ScenicSpotAdmin(admin.ModelAdmin): list_display (name, category, lng, lat, is_active) list_filter (category, is_active) search_fields (name, description) list_per_page 20 admin.register(PathEdge) class PathEdgeAdmin(admin.ModelAdmin): list_display (start_spot, end_spot, distance)我在实际配置中会额外处理一件事图片上传。景点图片字段用ImageField模板里要能够正确显示光是settings里配了MEDIA_ROOT还不够主urls.py还需要加一行from django.conf import settings from django.conf.urls.static import static urlpatterns [ # ... 其他URL配置 ] if settings.DEBUG: urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)不加这一行上传的图片URL能访问到但返回404页面里全是碎的图标非常掉价。4. 数据库设计与ORM实践4.1 数据模型设计数据库设计是答辩的另一个核心战场。我经常跟学生说不要求你设计得像大厂那样复杂但要做到“该有的字段一个不少该用的关系没有混乱”。这个项目的数据模型建议如下表名核心字段用途说明ScenicCategoryname景点分类自然景观、人文古迹、娱乐设施、公共服务ScenicSpotname, category(FK), lng, lat, description, image, is_active景点基本信息地图标注的数据源PathEdgestart_spot(FK), end_spot(FK), distance景点间可达路径路线规划的数据基础UserProfileuser(OneToOne), avatar, nickname用户扩展信息FavoriteRecorduser(FK), spot(FK), create_time用户收藏景点记录VisitHistoryuser(FK), spot(FK), visit_time用户浏览景点记录一个细节经纬度字段千万不要用FloatField应该用DecimalField(max_digits9, decimal_places6)。原因是浮点数在计算机里本身有精度损失而经纬度一旦误差到小数点后第5位地图上的标记就会明显偏移。DecimalField存储的是精确的定点数做位置数据更可靠。模型代码示例from django.db import models class ScenicCategory(models.Model): name models.CharField(max_length50, verbose_name分类名称) class Meta: verbose_name 景点分类 verbose_name_plural verbose_name def __str__(self): return self.name class ScenicSpot(models.Model): name models.CharField(max_length100, verbose_name景点名称) category models.ForeignKey(ScenicCategory, on_deletemodels.PROTECT, verbose_name所属分类) lng models.DecimalField(max_digits9, decimal_places6, verbose_name经度) lat models.DecimalField(max_digits9, decimal_places6, verbose_name纬度) description models.TextField(blankTrue, verbose_name景点描述) image models.ImageField(upload_tospots/, blankTrue, nullTrue, verbose_name景点图片) is_active models.BooleanField(defaultTrue, verbose_name是否展示) class Meta: verbose_name 景点 verbose_name_plural verbose_name def __str__(self): return self.name这里on_deletemodels.PROTECT是另一个容易忽视的细节。景点被收藏、被路线引用之后通常不应该允许被直接删掉。用PROTECT可以让数据库在有关联数据的时候拒绝删除保护数据完整性。答辩时被问到“你的数据怎么保证不混乱”这是一个讲起来很增色的点。4.2 查询优化与删除对象Django的ORM写起来方便但如果不注意N1查询问题页面一加载景点列表就卡。比如要展示每个景点及其分类名如果用ScenicSpot.objects.all()然后循环里访问spot.category.name每取一个景点就多一次SQL查询20个景点就是20条额外SQL。正确写法是spots ScenicSpot.objects.select_related(category).all()select_related会用一条JOIN把外键对应的分类一次性查出来20条SQL变成1条。如果是多对多关系则用prefetch_related。这个优化写到文档里答辩时主动提出来效果比被动等评委问好得多。再说删除对象。热搜词里有“django执行查询-删除对象”这一块坑不少。ORM里删除操作主要有几种方式。单个对象删除spot ScenicSpot.objects.get(id1) spot.delete()条件批量删除# 删除所有不展示的景点 ScenicSpot.objects.filter(is_activeFalse).delete()注意delete()返回值是一个元组第一个元素是删除的总行数含级联删除的行。这个行为对带外键的表非常重要如果景点表被FavoriteRecord外键引用且外键设置的是on_deletemodels.CASCADE删除景点会连带把收藏记录一起删掉。我一般建议收藏、日志这类数据保留所以外键用CASCADE还是PROTECT务必要在开发前想清楚。还有一个实战经验是“逻辑删除”优先于“物理删除”。给景点表加一个is_active字段后台“删除”改成“下架”数据在数据库里还在只是不再显示。这样误操作了还能恢复对演示现场也很友好。4.3 ORM常用操作整理为了方便新手照着抄我把这个项目里会用到的ORM操作整理一份速查# 新增记录 ScenicSpot.objects.create(name湖心亭, categorycategory, lng121.47, lat31.23) # 查询单条不存在抛DoesNotExist spot ScenicSpot.objects.get(id1) # 过滤 Spots.objects.filter(is_activeTrue).exclude(category__name施工封闭区) # 排序 spots ScenicSpot.objects.order_by(category__name, -id) # 聚合统计 from django.db.models import Count favorite_stats FavoriteRecord.objects.values(spot__name).annotate( countCount(id) ).order_by(-count) # 分页 from django.core.paginator import Paginator page_obj Paginator(ScenicSpot.objects.all(), 6).get_page(request.GET.get(page))这些操作覆盖了项目90%的数据请求场景。平时多敲几遍答辩现场讲系统时底气都不一样。5. 常见问题与远程调试经验5.1 环境搭建与项目跑通拿到源码之后第一步不是看代码而是先把项目跑起来。环境搭建的完整流程如下照着操作基本不会出错# 1. 创建虚拟环境 python -m venv venv # 2. 激活虚拟环境 venv\Scripts\activate # Windows source venv/bin/activate # Linux/macOS # 3. 安装依赖 pip install -r requirements.txt # 4. 生成数据库表 python manage.py makemigrations python manage.py migrate # 5. 创建管理后台账号 python manage.py createsuperuser # 6. 导入初始景点数据如果提供SQL文件 python manage.py loaddata initial_data.json # 7. 启动开发服务器 python manage.py runserver启动后浏览器访问http://127.0.0.1:8000首页就是地图导览界面访问http://127.0.0.1:8000/admin进入后台管理。这个流程看着简单实际上新手最常挂在第4步migrate上。报错信息通常是django.db.migrations.exceptions.InconsistentMigrationHistory或者各种字段冲突。遇到这种情况的第一反应应该是看项目中是否存在自己手动修改过的历史迁移文件最稳妥的办法是把app目录下migrations文件夹中除了__init__.py之外的文件全部删掉然后重新makemigrations和migrate。5.2 部署与静态文件问题清单本地跑通之后很多同学会把项目部署到云服务器上这时候会出现一系列本地环境没有的问题。我整理了一个高频问题速查表问题现象常见原因解决方案页面没有样式、图片全裂静态文件未配置或未collectstaticpython manage.py collectstatic并检查nginx中静态文件路径地图加载不出瓦片服务器无法访问外网或跨域确认服务器网络可访问OSM瓦片域名页面提示400/403/404ALLOWED_HOSTS未配置、DEBUGFalse在settings.py中配置ALLOWED_HOSTS为服务器域名或IP上传大图片报错请求体大小超限调整nginxclient_max_body_size 10m;SQLite数据库被锁并发访问过大生产环境切换到MySQL顺便说一个必须提醒的事项部署到服务器后一定把DEBUG False同时把SECRET_KEY换掉。否则服务一旦暴露在公网上Django会直接把错误堆栈信息打印给访客隐患非常大。这是毕设交付前必改的项。5.3 远程调试实操方法标题里提到的“远程调试”是很多学生第一次接触的概念。作为一个卖源码加调试服务的项目远程调试的本质是帮你把代码跑通、改对而不是代写。实操层面远程调试主要有两种方式。一种是局域网/公网环境下的浏览器开发者工具调试。前端在浏览器上按F12打开开发者工具Console面板能看到JS报错Network面板能看到页面请求了哪些接口、每个接口返回的状态码和数据。很多地图加载不出来、景点数据不显示的问题看Network面板一眼就能定位到是接口报错还是静态资源404。另一种是服务器端代码的交互式调试。推荐用VS Code的Remote SSH插件直接在本地编辑器打开服务器上的项目目录断点、单步执行、查看变量都能在服务器上实时操作。配置方式不复杂VS Code安装Remote SSH扩展配置好服务器的SSH连接信息和Python解释器路径其余操作和本地调试一模一样。Django端调试日志的信息量也很大。开发服务器默认会在控制台打印每一次SQL查询和请求耗时用python manage.py runserver --settingspark_project.settings_debug带上调试配置配合Django Debug Toolbar可以看到每个页面的SQL条数、缓存命中情况、页面耗时答辩时展示性能优化会特别直观。这里提醒一条远程调试的专属经验改代码前先备份改完一处就重启服务验证一处千万不要一次改几十行再统一重启。Django服务器支持热重载但失效的情况经常发生尤其修改了settings.py后。稳妥做法是每次改动后用python manage.py check检查一遍配置再重启服务器。5.4 源码交付与答辩要点这套题目在交付时除了源码外一般还会配套设计文档、操作手册和演示视频。我把近两年带项目时整理的《答辩前自查清单》列出来每一条都是踩过坑的数据库是否有测试数据答辩现场评委经常直接搜一个景点名称测试查询库里空的会非常尴尬。地图能否稳定加载提前准备好一个离线备用底图URL如果现场网络状况差还能保证页面不空。演示账号是否可用后台管理员账号、游客账号各准备一个密码写在文档里。图片素材是否本地化不要引用网络图片断了网就显示不出来。答辩PPT里是否包含架构图Django请求处理流程、数据库ER图、系统功能模块图这三张图是必放。答辩时如果被问到“这个路线规划是自己实现的吗”回答路径是这样先说整体用图建模景点是节点、道路是带权边然后说最短路径用的是Dijkstra算法推导一下它的时间复杂度再说说为什么不用Floyd单源最短路径场景下Dijkstra更快。能答出这一串评委基本不会再为难你。5.5 配合远程调试的避坑技巧很多学生远程调试的时候容易在环境差异上栽跟头我分享三条个人经验。第一版本一致性问题。本地开发用的是Python 3.10服务器上是3.11Django版本和数据库驱动版本不一致经常会出现ModuleNotFoundError或者某些ORM行为表现不同。最稳妥的做法是在项目根目录放一个requirements.txt并且明确标注Python版本要求pip freeze requirements.txt交付文档里写明“Python 3.10.x Django 3.2.x 已测试通过”能避免大量环境类问题。第二Windows和Linux路径分隔符不一致的问题。os.path.join和pathlib能自动处理但如果代码里硬编码了media\\spots\\xxx.jpg这样的路径在服务器上就找不到文件了。用os.path.join(media, spots, xxx.jpg)或者Path(media) / spots / xxx.jpg两边环境都不会出错。第三定位接口在远程服务器和本地的行为不同。本地是localhost访问还好一旦走IP访问HTTPS的限制就会出现前面已经讲过。远程调试的时候始终记住先看浏览器开发者工具的Network面板再看后端日志最后猜原因这个顺序能节省大量时间。6. 选题扩展与后续优化方向6.1 从毕设项目到完整产品的差距公园定位系统做完了、答辩通过了一定不是终点。这两年有不少学生会把项目继续完善参加比赛或者放到简历里。从一个能交的毕设到一个能拿得出手的项目中间还差几步优化。性能上景点查询、路线计算目前都是同步阻塞的并发上来以后MySQL扛不住。可以引入Redis做缓存热门景点列表、常用路线结果缓存5分钟响应时间能从几十毫秒降到个位数。查询本身再配合分页和懒加载页面首屏速度就上来了。功能上可以接入真实的地图API升级路线精度可以增加基于用户位置的“附近景点推荐”和“热门路线排行”管理端加一个简单的数据看板展示每日访客量、热门景点Top5让系统看起来更“智慧公园”。6.2 如果重新做一遍我会怎么做如果这个题让我重新实现一遍我会在架构上做一个调整前期就把Django作为纯API后端用Django REST Framework写接口前端完全独立出来用Vue或纯原生HTML做单页应用。这样做在毕设答辩上有更多话可以讲——前后端分离、RESTful接口设计、JWT认证——但代价是工作量会显著增加一个新手从零开始可能要一个半月以上才能完成。所以我的建议很明确如果你是第一次用Django做完整项目时间只有一个月左右就老老实实用Django模板加服务端渲染把精力花在功能完整性和代码质量上。可以接受“老套”一点的架构也不要烂尾。选题是公园定位不是前后端分离实战核心是做出来。这篇文章到这就算把公园定位系统的设计思路、技术实现、调试方法和交付要求都过了一遍。最后一句话送给大家毕设项目的意义不在于题目多大、技术多新而在于你是否真的把一个东西从头到尾做出来了并且能讲清楚每一个模块为什么这么设计。做到这一点不管测评老师怎么问你都能站稳脚跟上台答得漂漂亮亮。
返回列表