據(jù)分析+大模型:旅游景點(diǎn)信息可視化系統(tǒng)實(shí)戰(zhàn)解析)
這次我們來看一個(gè) Python 技術(shù)棧很全的實(shí)戰(zhàn)項(xiàng)目旅游景點(diǎn)信息可視化系統(tǒng)。它把 Django 后端框架、數(shù)據(jù)分析、可視化大屏、數(shù)據(jù)挖掘以及最近很火的大模型 Agent 和 DeepSeek 能力組合在一起做成一套完整的 Web 系統(tǒng)。實(shí)際在 CSDN 上這類項(xiàng)目經(jīng)常以課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)、求職作品集、期末大作業(yè)的形式出現(xiàn)但更重要的是它的技術(shù)鏈路非常適合用來練手幾乎可以覆蓋 Python 開發(fā)者在 Web 后端、數(shù)據(jù)處理、前端可視化、大模型接口對(duì)接這幾個(gè)方向上的核心技能。這篇文章不只講概念我會(huì)帶你把系統(tǒng)拆開看先看整體架構(gòu)和功能模塊再說本地部署怎么跑起來數(shù)據(jù)采集怎么做Django 后端怎么提供分析接口前端可視化大屏怎么接數(shù)據(jù)最后就是大模型 Agent 部分如何接入 DeepSeek、實(shí)現(xiàn)景點(diǎn)智能問答和數(shù)據(jù)分析自動(dòng)化。如果你在選課設(shè)題目、準(zhǔn)備畢設(shè)或者想在簡(jiǎn)歷里加一個(gè)“后端 數(shù)據(jù)分析 可視化 大模型”的完整項(xiàng)目這套系統(tǒng)可以作為一個(gè)很直接的參考。先說結(jié)論項(xiàng)目和標(biāo)題對(duì)應(yīng)的核心價(jià)值不只在“旅游景點(diǎn)信息管理”而是把Django 業(yè)務(wù)系統(tǒng)、數(shù)據(jù)分析結(jié)果可視化、大模型接入三條線都打通了。對(duì)于想學(xué) Django 和數(shù)據(jù)分析結(jié)合的人來說這套系統(tǒng)的模塊邊界比較清晰照著拆解能快速理解一個(gè) Web 應(yīng)用從數(shù)據(jù)到展示再到智能交互的完整路徑。1. 核心能力速覽能力項(xiàng)說明項(xiàng)目類型旅游景點(diǎn)信息可視化 Web 系統(tǒng)后端框架DjangoMTV 架構(gòu)數(shù)據(jù)分析使用 Pandas、NumPy 對(duì)景點(diǎn)評(píng)分、門票、評(píng)論、客流量等數(shù)據(jù)進(jìn)行統(tǒng)計(jì)分析可視化方式前端圖表展示常見為 ECharts / Chart.js可做成可視化大屏數(shù)據(jù)來源爬蟲采集或本地 CSV/Excel/JSON 數(shù)據(jù)集導(dǎo)入大模型能力接入 DeepSeek API實(shí)現(xiàn)旅游智能問答、數(shù)據(jù)分析 Agent啟動(dòng)方式命令行啟動(dòng) Django 開發(fā)服務(wù)器瀏覽器訪問是否支持 API支持Django 的視圖和 URL 可直接對(duì)外提供 JSON 接口是否支持批量任務(wù)支持可通過腳本批量采集、批量數(shù)據(jù)處理、批量生成分析報(bào)告推薦開發(fā)環(huán)境Python 3.8Django 3.2 / 4.x可搭配 MySQL 或 SQLite適合場(chǎng)景課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)、數(shù)據(jù)分析學(xué)習(xí)、Django Web 開發(fā)練習(xí)注意這里不寫死具體版本號(hào)因?yàn)椴煌?xiàng)目源碼使用的 Django 版本差異較大實(shí)際開發(fā)時(shí)以你拉取的代碼為準(zhǔn)建議先用虛擬環(huán)境隔離依賴。2. 適用場(chǎng)景與使用邊界這套系統(tǒng)適合四類人。第一類是計(jì)算機(jī)相關(guān)專業(yè)的學(xué)生。課程設(shè)計(jì)和畢業(yè)設(shè)計(jì)往往要求“系統(tǒng)要能跑起來、有數(shù)據(jù)、有圖表、有增刪改查”這套系統(tǒng)剛好全部覆蓋而且比普通的學(xué)生管理系統(tǒng)更有辨識(shí)度因?yàn)榧尤肓藬?shù)據(jù)分析和可視化大屏元素。第二類是正在學(xué) Django 的人。如果你只會(huì)寫簡(jiǎn)單的 Blog 或商城想進(jìn)階到“業(yè)務(wù)系統(tǒng) 數(shù)據(jù)分析 前端可視化”方向可以拿這個(gè)系統(tǒng)作為綜合練習(xí)。它不是普通的 CRUD 管理系統(tǒng)而是把數(shù)據(jù)分析結(jié)果通過圖表接口輸出對(duì) Django 的模型設(shè)計(jì)、視圖編碼、API 封裝要求更高。第三類是數(shù)據(jù)分析初學(xué)者。旅游景點(diǎn)相關(guān)的公開數(shù)據(jù)比較容易找到比如景點(diǎn)評(píng)分、門票價(jià)格、評(píng)論內(nèi)容、瀏覽量、地區(qū)分布等這些數(shù)據(jù)適合做清洗、統(tǒng)計(jì)、分組聚合和可視化展示比直接拿空泛的表格數(shù)據(jù)練習(xí)更有場(chǎng)景感。第四類是對(duì)大模型應(yīng)用感興趣的人。系統(tǒng)接入了 DeepSeek 之后能做到類似“幫我分析評(píng)分最高的十個(gè)景點(diǎn)并按地區(qū)統(tǒng)計(jì)”“生成一份三日旅游攻略”這樣的智能交互這就把大模型 Agent 落地到業(yè)務(wù)場(chǎng)景里了比單純聊天的 demo 更有實(shí)踐價(jià)值。使用邊界也要說清楚數(shù)據(jù)來源合法性問題。無論你是用爬蟲獲取數(shù)據(jù)還是用開源數(shù)據(jù)集都必須確保數(shù)據(jù)來源合法。爬取公共數(shù)據(jù)時(shí)要遵守目標(biāo)網(wǎng)站的 robots 協(xié)議、訪問頻率限制和相關(guān)法律不要爬取有版權(quán)保護(hù)的內(nèi)容不要對(duì)目標(biāo)站點(diǎn)造成訪問壓力。隱私與信息安全。系統(tǒng)如果包含用戶注冊(cè)登錄、評(píng)論、瀏覽歷史等功能需要對(duì)用戶數(shù)據(jù)進(jìn)行脫敏處理不能在中項(xiàng)目中硬編碼真實(shí)用戶密碼或身份證一類敏感信息。開發(fā)環(huán)境可以簡(jiǎn)單處理但一旦上線或用于畢業(yè)設(shè)計(jì)答辯展示就要按真實(shí)項(xiàng)目安全要求來。大模型使用合規(guī)。接入 DeepSeek 等大模型 API 時(shí)要遵守服務(wù)商的使用條款。不要將敏感數(shù)據(jù)提交到外部 API不要用大模型生成違法違規(guī)內(nèi)容。項(xiàng)目中應(yīng)設(shè)計(jì)過濾和審核機(jī)制尤其是用戶輸入直接進(jìn)入大模型時(shí)要做好提示詞邊界約束。防止過度夸大項(xiàng)目能力。這個(gè)系統(tǒng)不是真正的“大數(shù)據(jù)平臺(tái)”準(zhǔn)確說是一個(gè)帶有數(shù)據(jù)分析、可視化、大模型交互能力的 Web 應(yīng)用。“大數(shù)據(jù)”體現(xiàn)在它可以處理一定規(guī)模的結(jié)構(gòu)化數(shù)據(jù)例如數(shù)萬條景點(diǎn)點(diǎn)評(píng)數(shù)據(jù)而不是幾十 TB 的海量數(shù)據(jù)。3. 系統(tǒng)整體架構(gòu)與功能模塊在動(dòng)手部署之前先把系統(tǒng)拆開。理解模塊結(jié)構(gòu)比直接跑起來更重要因?yàn)槟阕稣n程設(shè)計(jì)或畢設(shè)時(shí)需要能講清楚每一部分是怎么設(shè)計(jì)的。3.1 技術(shù)架構(gòu)從整體架構(gòu)來看系統(tǒng)采用 Django 的 MTV 模式。Model 層設(shè)計(jì)景點(diǎn)信息、用戶、評(píng)論、收藏等數(shù)據(jù)表。Template 層負(fù)責(zé)頁面渲染但可視化大屏部分通常會(huì)用前端圖表庫動(dòng)態(tài)加載數(shù)據(jù)不依賴模板渲染數(shù)據(jù)。View 層負(fù)責(zé)業(yè)務(wù)邏輯一部分視圖返回 HTML 頁面一部分視圖返回 JSON 數(shù)據(jù)給前端圖表使用。數(shù)據(jù)庫方面開發(fā)階段用 SQLite 最簡(jiǎn)單部署和演示階段可以用 MySQL。數(shù)據(jù)分析部分可以使用 Pandas 直接讀取數(shù)據(jù)庫或 CSV 文件在 Django 視圖里完成數(shù)據(jù)聚合再序列化為 JSON 給前端。大模型 Agent 部分屬于新擴(kuò)展模塊一般單獨(dú)抽出一個(gè) app例如agent_service或ai_service。它負(fù)責(zé)接收前端傳來的用戶問題構(gòu)造 prompt調(diào)用 DeepSeek API把返回結(jié)果呈現(xiàn)給前端。3.2 核心功能模塊系統(tǒng)可以拆成下面幾個(gè)功能模塊。模塊名主要功能用戶模塊注冊(cè)、登錄、個(gè)人中心景點(diǎn)信息管理景點(diǎn)基本信息的增刪改查支持按照地區(qū)、價(jià)格、評(píng)分等字段篩選數(shù)據(jù)采集模塊爬蟲采集或批量導(dǎo)入景點(diǎn)數(shù)據(jù)數(shù)據(jù)分析模塊景點(diǎn)評(píng)分分布、價(jià)格區(qū)間、客流趨勢(shì)、評(píng)論情感分析等可視化大屏模塊地圖、柱狀圖、餅圖、折線圖展示分析結(jié)果大模型問答模塊基于 DeepSeek 的旅游智能問答和數(shù)據(jù)分析 Agent后臺(tái)管理模塊Django Admin 配置便于管理數(shù)據(jù)3.3 數(shù)據(jù)流設(shè)計(jì)系統(tǒng)數(shù)據(jù)流大概是這樣數(shù)據(jù)采集爬蟲 / 本地文件→ 數(shù)據(jù)清洗與入庫 → Django ORM 讀取數(shù)據(jù) → Pandas 聚合分析 → JSON API → 前端圖表渲染 ↓ DeepSeek Agent 接口 → 智能問答與自動(dòng)分析這個(gè)數(shù)據(jù)流的好處是每一層都能獨(dú)立測(cè)試。數(shù)據(jù)采集可以單獨(dú)跑一個(gè) Python 腳本不依賴 Web 系統(tǒng)。分析部分可以先用 Jupyter Notebook 驗(yàn)證再把分析邏輯遷移到 Django 視圖里。前端圖表和后端接口可以前后端分離調(diào)試大模型 Agent 可以單獨(dú)用curl或 Python 腳本測(cè)試。開發(fā)時(shí)按這個(gè)鏈路去拆分任務(wù)效率會(huì)高很多。4. 本地部署環(huán)境準(zhǔn)備部署這套系統(tǒng)不復(fù)雜但環(huán)境準(zhǔn)備要仔細(xì)。不同版本的 Django 對(duì) Python 版本有要求比如 Django 4.x 需要 Python 3.8Django 5.x 需要 Python 3.10。如果拉下來的代碼是老項(xiàng)目最好先看requirements.txt里的版本約束。4.1 基礎(chǔ)環(huán)境清單檢查項(xiàng)說明Python建議 3.8 到 3.11 之間兼容性最穩(wěn)包管理工具pip、virtualenv 或 condaDjango以項(xiàng)目 requirements.txt 為準(zhǔn)數(shù)據(jù)庫SQLite 開發(fā)最簡(jiǎn)單MySQL 適合演示前端圖表庫ECharts CDN 或本地靜態(tài)文件Node.js如果前端使用 Vite / Vue 構(gòu)建則需要Git拉取源碼、版本管理4.2 數(shù)據(jù)庫設(shè)計(jì)建議景點(diǎn)信息表通常包含以下字段景點(diǎn)名稱、城市、省份、區(qū)域、景區(qū)等級(jí)、門票價(jià)格、熱度、評(píng)分、評(píng)論數(shù)量、經(jīng)緯度、簡(jiǎn)介、封面圖片。如果做評(píng)論情感分析還需要評(píng)論表評(píng)論內(nèi)容、評(píng)分、時(shí)間、用戶 ID。如果想支持收藏功能就加一張收藏表。Django 中模型代碼大致如下from django.db import models class ScenicSpot(models.Model): name models.CharField(max_length128, verbose_name景點(diǎn)名稱) city models.CharField(max_length64, verbose_name城市) province models.CharField(max_length64, verbose_name省份) level models.CharField(max_length16, blankTrue, verbose_name景區(qū)等級(jí)) ticket_price models.FloatField(default0, verbose_name門票價(jià)格) score models.FloatField(default0, verbose_name評(píng)分) comment_count models.IntegerField(default0, verbose_name評(píng)論數(shù)) address models.CharField(max_length256, blankTrue, verbose_name地址) longitude models.FloatField(default0, verbose_name經(jīng)度) latitude models.FloatField(default0, verbose_name緯度) description models.TextField(blankTrue, verbose_name簡(jiǎn)介) created_at models.DateTimeField(auto_now_addTrue, verbose_name創(chuàng)建時(shí)間) class Meta: db_table scenic_spot verbose_name 景點(diǎn)信息 verbose_name_plural verbose_name def __str__(self): return self.name這個(gè)模型只是一個(gè)參考。實(shí)際項(xiàng)目里可以拆得更細(xì)比如把景區(qū)等級(jí)單獨(dú)做成一個(gè)字段選項(xiàng)把門票價(jià)格區(qū)間做成可篩選字段。5. 安裝部署與啟動(dòng)流程5.1 創(chuàng)建并激活虛擬環(huán)境建議每個(gè)項(xiàng)目一個(gè)獨(dú)立虛擬環(huán)境避免 Python 包沖突。Windows 下命令如下python -m venv venv venv\Scripts\activateLinux / macOS 下命令如下python3 -m venv venv source venv/bin/activate激活后命令行前面會(huì)出現(xiàn)(venv)標(biāo)識(shí)。如果python命令不可用可以檢查 Python 安裝路徑和環(huán)境變量。5.2 安裝依賴項(xiàng)目拉取下來后一般目錄里有requirements.txt執(zhí)行pip install -r requirements.txt如果缺少這個(gè)文件也可以手動(dòng)安裝核心依賴pip install django pandas numpy requests beautifulsoup4需要連接 MySQL 時(shí)還要安裝連接驅(qū)動(dòng)pip install pymysql mysqlclient安裝完成后可以通過pip list查看當(dāng)前環(huán)境中的包版本再對(duì)照項(xiàng)目要求確認(rèn)。5.3 修改配置文件Django 項(xiàng)目的配置文件通常是settings.py。需要重點(diǎn)關(guān)注 DATABASES 配置、INSTALLED_APPS、靜態(tài)文件路徑、允許訪問的主機(jī)列表。如果使用 SQLite默認(rèn)配置不需要改太多。如果使用 MySQL配置類似DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: tour_db, USER: root, PASSWORD: your_password, HOST: 127.0.0.1, PORT: 3306, } }還需要在項(xiàng)目__init__.py中添加import pymysql pymysql.install_as_MySQLdb()5.4 執(zhí)行數(shù)據(jù)庫遷移Django 會(huì)通過遷移文件自動(dòng)創(chuàng)建數(shù)據(jù)表python manage.py makemigrations python manage.py migrate執(zhí)行后數(shù)據(jù)庫里會(huì)出現(xiàn)項(xiàng)目定義的數(shù)據(jù)表。如果遷移過程報(bào)錯(cuò)通常是依賴問題或者模型定義問題具體排查方法后面章節(jié)會(huì)講。5.5 創(chuàng)建管理員賬號(hào)進(jìn)入 Django Admin 后臺(tái)需要超級(jí)用戶python manage.py createsuperuser按提示輸入用戶名、郵箱、密碼。如果密碼強(qiáng)度不夠Django 會(huì)提醒但可以強(qiáng)制確認(rèn)。5.6 啟動(dòng)開發(fā)服務(wù)器python manage.py runserver默認(rèn)訪問地址是http://127.0.0.1:8000。如果需要局域網(wǎng)內(nèi)其他設(shè)備訪問可以指定0.0.0.0python manage.py runserver 0.0.0.0:8000啟動(dòng)成功后瀏覽器打開首頁能看到系統(tǒng)主界面。如果頁面打不開先看終端里的日志確認(rèn)端口是否沖突或者是否還有報(bào)錯(cuò)。6. 數(shù)據(jù)采集與數(shù)據(jù)預(yù)處理數(shù)據(jù)是這套系統(tǒng)的核心。沒有景點(diǎn)數(shù)據(jù)后面的分析和可視化都是空談。所以數(shù)據(jù)采集和清洗這一步必須單獨(dú)拿出來講。6.1 數(shù)據(jù)采集方式在真實(shí)場(chǎng)景中數(shù)據(jù)可以來自公開的旅游數(shù)據(jù)平臺(tái)、景區(qū)官網(wǎng)、政府公開數(shù)據(jù)接口或者你自己構(gòu)造的測(cè)試數(shù)據(jù)。對(duì)于學(xué)生項(xiàng)目比較推薦的做法是找開源數(shù)據(jù)集或者手工整理一部分高質(zhì)量數(shù)據(jù)避免爬蟲帶來的法律風(fēng)險(xiǎn)。如果必須使用爬蟲采集要嚴(yán)格遵守合規(guī)原則只采集允許訪問的公開信息控制請(qǐng)求頻率不抓取個(gè)人隱私數(shù)據(jù)。一個(gè)最簡(jiǎn)單的請(qǐng)求示例import requests from bs4 import BeautifulSoup headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } url https://example.com/scenic response requests.get(url, headersheaders, timeout10) response.encoding utf-8 soup BeautifulSoup(response.text, html.parser) items soup.select(.scenic-item) for item in items: name item.select_one(.name).text.strip() price item.select_one(.price).text.strip() print(name, price)注意實(shí)際爬取時(shí)目標(biāo)站點(diǎn)的頁面結(jié)構(gòu)和反爬策略會(huì)復(fù)雜很多這里只展示最基本的思路。對(duì)于課程設(shè)計(jì)建議不要依賴爬蟲作為唯一的數(shù)據(jù)來源要準(zhǔn)備一份靜態(tài) CSV 文件作為兜底確保系統(tǒng)在任何時(shí)候都能演示。6.2 數(shù)據(jù)清洗與入庫用 Pandas 清洗數(shù)據(jù)非常方便。讀取 CSV 后可以統(tǒng)一字段名、去除空值、轉(zhuǎn)換價(jià)格和評(píng)分為數(shù)值類型再寫入數(shù)據(jù)庫。import pandas as pd from your_app.models import ScenicSpot df pd.read_csv(scenic_data.csv) df df.dropna(subset[name]) # 去除名字為空的數(shù)據(jù) df[price] pd.to_numeric(df[price], errorscoerce).fillna(0) df[score] pd.to_numeric(df[score], errorscoerce).fillna(0) for _, row in df.iterrows(): ScenicSpot.objects.update_or_create( namerow[name], defaults{ city: row.get(city, ), province: row.get(province, ), level: row.get(level, ), ticket_price: row[price], score: row[score], address: row.get(address, ), longitude: row.get(longitude, 0), latitude: row.get(latitude, 0), description: row.get(description, ), } )這里使用update_or_create是為了避免重復(fù)寫入適合重復(fù)執(zhí)行數(shù)據(jù)導(dǎo)入腳本。大批量數(shù)據(jù)導(dǎo)入時(shí)可以用bulk_create提升速度但要注意主鍵沖突問題。6.3 數(shù)據(jù)分析流程數(shù)據(jù)入庫之后可以用 Pandas 在 Django 視圖里直接做聚合分析。一個(gè)典型場(chǎng)景是統(tǒng)計(jì)各省份的景點(diǎn)數(shù)量和平均評(píng)分from django.http import JsonResponse import pandas as pd from your_app.models import ScenicSpot def province_stats(request): queryset ScenicSpot.objects.all().values(province, score, ticket_price) df pd.DataFrame(list(queryset)) if df.empty: return JsonResponse({code: 0, data: []}) result ( df.groupby(province) .agg(spot_count(province, count), avg_score(score, mean)) .reset_index() .sort_values(spot_count, ascendingFalse) .head(10) ) data result.to_dict(orientrecords) return JsonResponse({code: 0, data: data})這種方式的好處是分析邏輯全部放在后端前端只需要拿到 JSON 數(shù)據(jù)再渲染圖表前后端職責(zé)清晰答辯時(shí)也能解釋清楚。7. 可視化大屏呈現(xiàn)可視化部分是系統(tǒng)最直觀的亮點(diǎn)。完成數(shù)據(jù)分析之后前端需要把結(jié)果展示出來。對(duì)于旅游景點(diǎn)系統(tǒng)常見的可視化形式包括地圖分布圖、柱狀圖、餅圖、折線圖、雷達(dá)圖和詞云圖。以 ECharts 為例前端頁面可以這樣調(diào)用后端接口!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title旅游景點(diǎn)可視化大屏/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script style #chart { width: 100%; height: 500px; } /style /head body div idchart/div script fetch(/api/province-stats/) .then(response response.json()) .then(data { const chart echarts.init(document.getElementById(chart)); const provinces data.data.map(item item.province); const counts data.data.map(item item.spot_count); chart.setOption({ title: { text: 各省份景點(diǎn)數(shù)量 TOP10 }, tooltip: {}, xAxis: { type: category, data: provinces }, yAxis: { type: value }, series: [ { name: 景點(diǎn)數(shù)量, type: bar, data: counts, itemStyle: { color: #5470c6 } } ] }); }); /script /body /html在大屏場(chǎng)景中可以把多個(gè)圖表并排排列再加一些滾動(dòng)數(shù)據(jù)、地圖標(biāo)記整體效果會(huì)更接近商業(yè)可視化大屏。但要注意大屏的核心價(jià)值是“信息有效傳達(dá)”不要為了炫技堆太多裝飾元素。可視化部分還應(yīng)該支持?jǐn)?shù)據(jù)聯(lián)動(dòng)或篩選。例如用戶選擇一個(gè)省份下面的價(jià)格分布圖、評(píng)分區(qū)間圖、景區(qū)等級(jí)圖都跟著變化。這部分邏輯可以放在 Vue 或原生 JavaScript 中通過向后端發(fā)送篩選參數(shù)實(shí)現(xiàn)。8. 接入 DeepSeek 大模型與 Agent 智能問答這一塊是系統(tǒng)從“傳統(tǒng)管理系統(tǒng)”升級(jí)到“智能應(yīng)用”的關(guān)鍵。DeepSeek 是目前應(yīng)用比較廣的大模型服務(wù)之一它提供了 API 接口可以在不部署本地模型的情況下快速接入。這樣一來系統(tǒng)就可以實(shí)現(xiàn)用戶自然語言提問自動(dòng)生成分析結(jié)論或旅行建議。8.1 設(shè)計(jì)思路Agent 模塊不只是一個(gè)簡(jiǎn)單的聊天機(jī)器人而是要跟系統(tǒng)數(shù)據(jù)結(jié)合起來。例如用戶問“杭州有哪些評(píng)分 4.5 以上的景點(diǎn)”系統(tǒng)可以先從數(shù)據(jù)庫查出這些景點(diǎn)再拼接成提示詞讓大模型生成一段更自然的回答或者直接讓大模型生成 SQL 查詢條件系統(tǒng)執(zhí)行查詢后返回結(jié)果。更簡(jiǎn)單可靠的方案是“查詢結(jié)果 大模型潤(rùn)色”。即先用 Django ORM 或 Pandas 完成數(shù)據(jù)查詢?cè)侔巡樵兘Y(jié)果放入 prompt讓大模型生成總結(jié)性文字。這樣避免了讓大模型直接生成不可控的 SQL也避免了回答與真實(shí)數(shù)據(jù)不一致的問題。8.2 API 調(diào)用示例使用 Python requests 調(diào)用 DeepSeek API 的通用流程如下具體地址和參數(shù)以官方文檔為準(zhǔn)import requests API_URL https://api.deepseek.com/v1/chat/completions API_KEY your_api_key # 從服務(wù)商控制臺(tái)獲取注意不要提交到公開倉庫 def chat_with_deepseek(user_question, context): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } messages [ { role: system, content: 你是一個(gè)旅游數(shù)據(jù)分析助手基于給定的數(shù)據(jù)回答問題?;卮鹨?jiǎn)潔、準(zhǔn)確。 } ] if context: messages.append({ role: user, content: f以下是數(shù)據(jù)內(nèi)容\n{context}\n\n用戶問題{user_question} }) else: messages.append({ role: user, content: user_question }) payload { model: deepseek-chat, messages: messages, temperature: 0.3, stream: False } response requests.post(API_URL, jsonpayload, headersheaders, timeout60) response.raise_for_status() data response.json() return data[choices][0][message][content]實(shí)際接入時(shí)需要注意API Key 絕對(duì)不能硬編碼在前端代碼中要放在后端環(huán)境變量或配置文件中。調(diào)用大模型 API 會(huì)產(chǎn)生費(fèi)用開發(fā)階段要控制調(diào)用次數(shù)設(shè)置合理的超時(shí)時(shí)間。用戶輸入不可直接作為 prompt 不加約束地傳給大模型要在系統(tǒng)提示詞中明確邊界防止提示詞注入。對(duì)返回內(nèi)容要做基本的校驗(yàn)和展示處理避免前端直接渲染不可信內(nèi)容。8.3 Agent 化設(shè)計(jì)更完整的 Agent 設(shè)計(jì)可以增加一個(gè)簡(jiǎn)單的“工具選擇”機(jī)制。系統(tǒng)預(yù)先定義幾個(gè)函數(shù)例如按城市查詢景點(diǎn)、按評(píng)分篩選、計(jì)算平均價(jià)格、生成旅游攻略。大模型收到用戶問題后先判斷需要調(diào)用哪個(gè)函數(shù)然后由系統(tǒng)執(zhí)行函數(shù)再把函數(shù)結(jié)果返回給大模型組織語言。這個(gè)流程在 Django 里可以簡(jiǎn)化成多輪智能問答接口def agent_question(request): if request.method POST: question request.POST.get(question, ) city request.POST.get(city, ) context get_city_stats(city) # 查詢數(shù)據(jù)庫獲得統(tǒng)計(jì)摘要 if context: answer chat_with_deepseek(question, context) else: answer chat_with_deepseek(question) return JsonResponse({code: 0, answer: answer})這樣一個(gè)簡(jiǎn)單的 Agent 就能讓系統(tǒng)回答“某城市的景點(diǎn)數(shù)量”“平均票價(jià)”“評(píng)分最高的景點(diǎn)推薦”等問題而且回答有數(shù)據(jù)庫數(shù)據(jù)作為支撐不是憑空生成。9. 接口 API 與批量任務(wù)設(shè)計(jì)當(dāng)系統(tǒng)功能穩(wěn)定后你可能希望把能力開放給其他模塊或小程序調(diào)用。這時(shí)就需要設(shè)計(jì)規(guī)范的接口 API 和批量任務(wù)處理方案。9.1 接口 APIDjango 中既可以用原生 JsonResponse也可以用 Django REST FrameworkDRF完成接口開發(fā)。DRF 的優(yōu)勢(shì)在于序列化、分頁、認(rèn)證、權(quán)限管理都內(nèi)置了代碼結(jié)構(gòu)更規(guī)范。一個(gè)簡(jiǎn)單 API 視圖示例from rest_framework.decorators import api_view from rest_framework.response import Response from your_app.models import ScenicSpot from your_app.serializers import ScenicSpotSerializer api_view([GET]) def scenic_list(request): province request.query_params.get(province, ) queryset ScenicSpot.objects.all() if province: queryset queryset.filter(provinceprovince) serializer ScenicSpotSerializer(queryset, manyTrue) return Response({code: 0, data: serializer.data})接口設(shè)計(jì)建議接口路徑方法功能/api/scenic/GET獲取景點(diǎn)列表支持按省份、城市、價(jià)格篩選/api/scenic/ /GET獲取景點(diǎn)詳情/api/province-stats/GET獲取各省份景點(diǎn)統(tǒng)計(jì)/api/price-distribution/GET獲取價(jià)格分布數(shù)據(jù)/api/agent/chat/POST大模型智能問答接口9.2 批量任務(wù)數(shù)據(jù)分析場(chǎng)景經(jīng)常需要批量處理任務(wù)例如批量更新天氣數(shù)據(jù)、批量導(dǎo)入新景點(diǎn)、批量生成日?qǐng)?bào)。Django 中可以用 management command 實(shí)現(xiàn)后臺(tái)定時(shí)任務(wù)也可以用普通的 Python 腳本循環(huán)處理。批量分析腳本示例# your_app/management/commands/batch_analyze.py from django.core.management.base import BaseCommand import pandas as pd from your_app.models import ScenicSpot class Command(BaseCommand): help 批量統(tǒng)計(jì)景點(diǎn)數(shù)據(jù)并生成 CSV 報(bào)告 def handle(self, *args, **options): queryset ScenicSpot.objects.all().values(province, score, ticket_price) df pd.DataFrame(list(queryset)) if df.empty: self.stdout.write(no data) return grouped df.groupby(province).agg( count(province, count), avg_score(score, mean), avg_price(ticket_price, mean) ).reset_index() output_path reports/scenic_summary.csv grouped.to_csv(output_path, indexFalse, encodingutf-8-sig) self.stdout.write(freport saved to {output_path})執(zhí)行方式python manage.py batch_analyze批量任務(wù)要注意日志記錄和冪等性。設(shè)計(jì)任務(wù)時(shí)要考慮“任務(wù)中途失敗后是否可以重新執(zhí)行”避免重復(fù)數(shù)據(jù)或臟數(shù)據(jù)。更復(fù)雜的批量場(chǎng)景可以引入 Celery 或 Django-Q但對(duì)于課程設(shè)計(jì)和中小型項(xiàng)目腳本方式已經(jīng)完全夠用。10. 資源占用與性能觀察雖然這是 Web 項(xiàng)目不像大模型本地推理那樣過分依賴顯存但啟動(dòng)和運(yùn)行時(shí)的資源占用仍然值得關(guān)注。這里提供一個(gè)觀察思路。10.1 啟動(dòng)階段資源占用啟動(dòng) Django 服務(wù)后系統(tǒng)會(huì)加載 Python 解釋器、Django 框架和必要的第三方依賴內(nèi)存占用一般在幾十 MB 到幾百 MB 之間具體取決于項(xiàng)目依賴數(shù)量和模型加載情況。如果集成了較大的 Pandas 數(shù)據(jù)處理邏輯在導(dǎo)入大量數(shù)據(jù)時(shí)內(nèi)存會(huì)明顯上升。給一個(gè)通用觀察命令# Linux / macOS 下查看 Python 進(jìn)程內(nèi)存占用 ps aux | grep python # Windows 下可以在任務(wù)管理器中查看對(duì)應(yīng)的 python.exe 進(jìn)程10.2 接口響應(yīng)性能影響接口響應(yīng)速度的主要因素有三個(gè)第一是數(shù)據(jù)庫查詢量。Django ORM 查詢?nèi)绻褂貌划?dāng)會(huì)在循環(huán)中產(chǎn)生大量額外查詢導(dǎo)致響應(yīng)變慢。解決辦法是用select_related和prefetch_related減少查詢次數(shù)數(shù)據(jù)量大時(shí)加索引。第二是數(shù)據(jù)聚合計(jì)算。Pandas 處理幾萬條數(shù)據(jù)通常很快但如果每次請(qǐng)求都實(shí)時(shí)做全量 groupby在高并發(fā)下會(huì)有壓力。緩解方案是提前計(jì)算好統(tǒng)計(jì)結(jié)果緩存到 Redis 或內(nèi)存中定時(shí)刷新。第三是外部 API 調(diào)用。DeepSeek 等大模型接口的響應(yīng)時(shí)間一般在幾秒到幾十秒之間這是系統(tǒng)的性能瓶頸。如果在用戶請(qǐng)求的同步鏈路中直接調(diào)用用戶會(huì)感覺卡頓。改進(jìn)方案是異步調(diào)用或者先生成短緩存再輪詢結(jié)果。10.3 降低資源占用的手段如果內(nèi)存或 CPU 資源有限可以從幾個(gè)方向優(yōu)化用更大批量方式寫入數(shù)據(jù)避免頻繁操作數(shù)據(jù)庫。分析結(jié)果緩存減少重復(fù)計(jì)算。在數(shù)據(jù)庫中建立常用字段索引。前端圖表數(shù)據(jù)加緩存策略不必每次刷新都請(qǐng)求最新數(shù)據(jù)。大模型 API 結(jié)果緩存相同問題直接返回上次結(jié)果。11. 常見問題與排查方法問題現(xiàn)象可能原因排查方式解決方案pip install -r requirements.txt安裝失敗依賴包版本沖突或 Python 版本不匹配檢查報(bào)錯(cuò)信息中的包名和版本號(hào)查看當(dāng)前 Python 版本嘗試換 Python 版本或者手動(dòng)安裝單個(gè)依賴包python manage.py migrate報(bào)錯(cuò)數(shù)據(jù)庫連接失敗、驅(qū)動(dòng)缺失或模型字段有問題查看完整報(bào)錯(cuò)堆棧檢查 DATABASES 配置安裝對(duì)應(yīng)數(shù)據(jù)庫驅(qū)動(dòng)檢查數(shù)據(jù)庫賬號(hào)密碼權(quán)限核對(duì)模型字段啟動(dòng)runserver后提示端口被占用8000 端口已被其他程序使用查看終端報(bào)錯(cuò)提示在瀏覽器訪問對(duì)應(yīng)端口確認(rèn)更換端口python manage.py runserver 8080頁面能打開但圖表是空白前端 JS 報(bào)錯(cuò)、接口返回?cái)?shù)據(jù)為空、接口路徑不對(duì)打開瀏覽器開發(fā)者工具查看 Console 和 Network 請(qǐng)求確認(rèn)接口地址正確檢查后端返回的 JSON 是否有數(shù)據(jù)接口返回 500Django 視圖代碼異?;驍?shù)據(jù)庫查詢出錯(cuò)查看 Django 運(yùn)行日志定位報(bào)錯(cuò)文件和行號(hào)根據(jù)報(bào)錯(cuò)修改代碼檢查數(shù)據(jù)是否存在和字段是否為空DeepSeek API 調(diào)用超時(shí)或失敗網(wǎng)絡(luò)不穩(wěn)定、API Key 失效、請(qǐng)求參數(shù)錯(cuò)誤、余額不足先用curl或簡(jiǎn)單腳本測(cè)試 API Key 是否可用檢查 API 配置調(diào)整超時(shí)時(shí)間確認(rèn)調(diào)用方式和額度爬蟲采集數(shù)據(jù)被反爬請(qǐng)求頻率過高或缺少瀏覽器請(qǐng)求頭查看響應(yīng)狀態(tài)碼和頁面內(nèi)容降低請(qǐng)求頻率增加隨機(jī) User-Agent或者改用公開數(shù)據(jù)集批量分析腳本重復(fù)寫入數(shù)據(jù)腳本沒有做冪等處理檢查寫入邏輯中是否有唯一性判斷使用update_or_create或先查詢?cè)賹懭隓jango Admin 后臺(tái)打不開未創(chuàng)建超級(jí)用戶或未注冊(cè)模型執(zhí)行createsuperuser創(chuàng)建賬號(hào)檢查admin.py注冊(cè)代碼注冊(cè)模型并在admin.py中注冊(cè)網(wǎng)頁顯示跨域錯(cuò)誤前端和后端不在同一個(gè)域名/端口查看瀏覽器 Network 請(qǐng)求的 CORS 報(bào)錯(cuò)開發(fā)階段可以配置 Django CORS 插件或使用反向代理12. 最佳實(shí)踐與使用建議最后分享幾個(gè)工程化建議這些經(jīng)驗(yàn)適用于任何 Django 數(shù)據(jù)分析 可視化 大模型項(xiàng)目不只是旅游景點(diǎn)系統(tǒng)。第一保留一套最小可運(yùn)行配置。開發(fā)初期不要一上來就接 MySQL、Redis、大模型 API先讓系統(tǒng)在 SQLite 和默認(rèn)配置下跑通再逐步替換組件。這樣可以快速定位問題是出在業(yè)務(wù)代碼還是基礎(chǔ)設(shè)施上。第二數(shù)據(jù)、代碼、輸出目錄分離。建議目錄結(jié)構(gòu)如下project/ ├── data/ │ ├── raw/ # 原始采集數(shù)據(jù) │ ├── clean/ # 清洗后的數(shù)據(jù) │ └── reports/ # 分析報(bào)告 ├── static/ │ ├── css/ │ ├── js/ │ └── images/ ├── templates/ └── your_app/這樣你的數(shù)據(jù)采集腳本、分析腳本、Django 項(xiàng)目代碼之間不會(huì)互相污染后期寫文檔和復(fù)盤也更方便。第三批量任務(wù)一定要加日志和失敗重試。數(shù)據(jù)清洗和數(shù)據(jù)處理腳本經(jīng)常會(huì)因?yàn)閭€(gè)別臟數(shù)據(jù)導(dǎo)致中斷處理每條數(shù)據(jù)時(shí)建議用try...except捕獲異常并記錄到日志文件而不是讓整個(gè)腳本崩潰。第四大模型接口要預(yù)留開關(guān)。開發(fā)階段可能不想耗費(fèi) API 額度可以在配置文件中加一個(gè)大模型啟用開關(guān)。關(guān)閉時(shí)系統(tǒng)仍然可以完成數(shù)據(jù)分析和可視化展示打開時(shí)才調(diào)用 DeepSeek這樣調(diào)試會(huì)更可控。第五涉及版權(quán)、人臉、聲音、數(shù)據(jù)來源時(shí)務(wù)必確認(rèn)授權(quán)。雖然旅游景點(diǎn)信息屬于公開信息但評(píng)論內(nèi)容、圖片素材仍然可能存在版權(quán)歸屬問題。在課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)或個(gè)人學(xué)習(xí)中盡量使用自有數(shù)據(jù)或明確授權(quán)來源的數(shù)據(jù)如果項(xiàng)目后續(xù)要公開發(fā)布或商用必須做更嚴(yán)格的合規(guī)審查。第六發(fā)布到線上之前要關(guān)閉 Django DEBUG 模式。同時(shí)要設(shè)置ALLOWED_HOSTS為實(shí)際域名或 IP否則會(huì)出現(xiàn)安全報(bào)錯(cuò)。13. 總結(jié)與下一步這套旅游景點(diǎn)信息可視化系統(tǒng)值得動(dòng)手的地方有三個(gè)一是能跑通一條完整的數(shù)據(jù)鏈路從采集、清洗、分析到可視化展示二是 Django 項(xiàng)目本身的結(jié)構(gòu)比較規(guī)范適合做課程設(shè)計(jì)或畢業(yè)設(shè)計(jì)二次開發(fā)三是大模型 Agent 接入讓系統(tǒng)有了更多可擴(kuò)展的想象空間不再停留在簡(jiǎn)單的增刪改查。建議你先用一份 CSV 測(cè)試數(shù)據(jù)把系統(tǒng)跑通再逐步替換成爬蟲數(shù)據(jù)和大模型接口。最容易踩的坑集中在數(shù)據(jù)庫配置、依賴版本沖突、接口返回?cái)?shù)據(jù)格式不一致這三類遇到問題先看日志再按上面排查表逐一處理。后續(xù)可以繼續(xù)擴(kuò)展的方向包括接入實(shí)時(shí)天氣數(shù)據(jù)、評(píng)論情感分析、用戶推薦系統(tǒng)、移動(dòng)端適配、部署到云服務(wù)器、把大模型 Agent 擴(kuò)展到更復(fù)雜的多輪對(duì)話和自動(dòng)化報(bào)告生成。每一步都是在現(xiàn)有項(xiàng)目上疊加能力不會(huì)推翻重來。如果你正在找可以寫進(jìn)簡(jiǎn)歷的 Python 實(shí)戰(zhàn)項(xiàng)目建議把重點(diǎn)放在數(shù)據(jù)清洗邏輯、可視化大屏設(shè)計(jì)、接口封裝和大模型 Agent 這四塊它們分別對(duì)應(yīng)數(shù)據(jù)分析、前端展示、后端開發(fā)和 AI 應(yīng)用四個(gè)熱門方向比較能體現(xiàn)綜合工程能力。