全球城市生活成本数据可视化分析系统 - 技术文档
目录
1. 项目概述
1.1 系统简介
本系统是一个基于 Django 框架的全球城市生活成本数据可视化分析平台,旨在为用户提供全球主要城市的生活成本数据查询、对比分析和可视化展示。系统基于 Numbeo 公开数据集,涵盖全球 5000+ 城市的 57 项生活成本指标,包括餐饮、交通、住房、教育、娱乐等多个维度。
1.2 核心功能
| 功能模块 | 说明 |
|---|---|
| 数据看板 | 全局统计概览、国家排名、雷达图、散点图、热力图、城市推荐 |
| 数据管理 | 城市生活成本记录的增删改查、CSV 导入导出 |
| 城市对比 | 多城市多维度雷达图 + 柱状图对比分析 |
| 购买力分析 | 各国工资对 17 种日常商品的购买力对比 |
| 分布分析 | 各指标的直方图分布 + 描述性统计(均值、中位数、标准差、四分位数) |
| 区域分析 | 按大洲划分的区域生活成本对比 |
| 成本结构 | 各国生活成本的六大类别占比分析(饼图 + 柱状图) |
| 负担力排名 | 各国工资对基本生活开支的覆盖率排名 |
| 租金预测 | 基于线性回归的市中心一居室月租预测 |
1.3 数据来源
数据集来源于 Numbeo,采集时间为 2022 年 12 月 3 日,包含 63 列数据(其中 57 项为数值型生活成本指标),编码格式为 GB18030。




























2. 技术栈
2.1 后端
| 组件 | 版本 | 用途 |
|---|---|---|
| Python | 3.x | 运行环境 |
| Django | 4.2.8 | Web 框架 |
| django-simpleui | -- | Django Admin 美化界面 |
| MySQL | -- | 关系型数据库 |
| mysqlclient | 2.2.0 | MySQL 数据库驱动 |
| PyMySQL | 1.1.1 | MySQL 备选驱动 |
| pandas | 2.2.3 | CSV 数据处理 |
| scikit-learn | 1.3.2 | 机器学习(线性回归预测) |
2.2 前端
| 组件 | 版本 | 来源 | 用途 |
|---|---|---|---|
| Bootstrap CSS | 5.3.3 | CDN | UI 框架 |
| Bootstrap JS | 5.3.3 | CDN | 交互组件 |
| Bootstrap Icons | 1.11.3 | CDN | 图标库 |
| ECharts | 5.5.1 | CDN | 数据可视化图表 |
| Inter Font | -- | Google Fonts | 字体 |
2.3 架构模式
采用 Django 的 MVT(Model-View-Template) 架构模式:
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ Template │◄────│ View │◄────│ Model │
│ (HTML/CSS/ │ │ (业务逻辑) │ │ (数据层/ORM) │
│ JS) │ │ │ │ │
└─────────────┘ └──────┬──────┘ └───────────────┘
│
┌──────▼──────┐
│ MySQL DB │
└─────────────┘
3. 项目结构
city/
├── citycost/ # Django 项目配置包
│ ├── __init__.py
│ ├── settings.py # 项目配置(数据库、中间件、应用等)
│ ├── urls.py # 根 URL 路由
│ ├── wsgi.py # WSGI 入口
│ └── asgi.py # ASGI 入口
│
├── dashboard/ # 主应用
│ ├── __init__.py
│ ├── admin.py # Admin 后台注册
│ ├── apps.py # 应用配置
│ ├── forms.py # 表单定义(3 个表单类)
│ ├── models.py # 数据模型(2 个模型 + CSV 映射常量)
│ ├── urls.py # 应用 URL 路由(40 条规则)
│ ├── views.py # 视图函数(28 个视图)
│ │
│ ├── management/
│ │ └── commands/
│ │ ├── create_admin.py # 创建默认管理员
│ │ ├── import_cost_data.py # CSV 数据导入
│ │ └── populate_chinese_names.py # 中文名称填充
│ │
│ ├── migrations/ # 数据库迁移文件
│ │ ├── 0001_initial.py
│ │ ├── 0002_userfavorite.py
│ │ └── 0003_costoflivingrecord_city_cn_and_more.py
│ │
│ ├── static/dashboard/
│ │ ├── css/
│ │ │ └── app.css # 全局样式(1285 行设计系统)
│ │ ├── images/
│ │ │ └── city-bg.jpg # 登录/注册页背景图
│ │ └── js/
│ │ ├── charts.js # 首页看板图表(273 行)
│ │ ├── city_compare.js # 城市对比图表
│ │ ├── purchasing_power.js # 购买力分析图表
│ │ ├── distribution.js # 分布分析图表
│ │ ├── regional.js # 区域分析图表
│ │ ├── cost_structure.js # 成本结构图表
│ │ └── affordability.js # 负担力排名图表
│ │
│ └── templates/
│ ├── registration/
│ │ └── login.html # 登录页
│ └── dashboard/
│ ├── base.html # 基础布局模板(侧边栏 + 顶栏)
│ ├── index.html # 数据看板首页
│ ├── register.html # 注册页
│ ├── profile.html # 个人中心
│ ├── record_list.html # 数据列表
│ ├── record_detail.html # 城市详情
│ ├── record_form.html # 新增/编辑表单
│ ├── record_confirm_delete.html # 删除确认
│ ├── record_import.html # CSV 导入
│ ├── predict.html # 租金预测
│ ├── city_compare.html # 城市对比
│ ├── purchasing_power.html # 购买力分析
│ ├── distribution.html # 分布分析
│ ├── regional.html # 区域分析
│ ├── cost_structure.html # 成本结构
│ └── affordability.html # 负担力排名
│
├── cost-of-living_20221203.csv # Numbeo 原始数据集
├── requirements.txt # Python 依赖清单
├── gen_all_mappings.py # 城市中文名音译生成器
├── build_mapping.py # 映射构建脚本
├── generate_city_names.py # 城市名生成脚本
├── unmapped_cities.txt # 未映射城市列表
├── all_cities.txt # 全部城市列表
└── cities_by_country.txt # 按国家分组的城市列表
4. 环境搭建与部署
4.1 系统要求
- Python 3.8+
- MySQL 5.7+ / 8.0
- pip 包管理器
4.2 安装步骤
bash
# 1. 克隆或解压项目
cd city
# 2. 创建虚拟环境(推荐)
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\Scripts\activate # Windows
# 3. 安装 Python 依赖
pip install -r requirements.txt
# 4. 创建 MySQL 数据库
mysql -u root -p
CREATE DATABASE design_133_city CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EXIT;
# 5. 执行数据库迁移
python manage.py migrate
# 6. 导入生活成本数据
python manage.py import_cost_data --path cost-of-living_20221203.csv
# 7. 填充中文城市/国家名称
python manage.py populate_chinese_names
# 8. 创建管理员账号
python manage.py create_admin
# 9. 启动开发服务器
python manage.py runserver
4.3 默认管理员账号
| 字段 | 值 |
|---|---|
| 用户名 | admin |
| 密码 | 123456 |
| 邮箱 | admin@example.com |
注意 :
create_admin命令会重置已存在管理员的密码为123456。
4.4 访问地址
| 地址 | 说明 |
|---|---|
http://127.0.0.1:8000/ |
系统首页(需登录) |
http://127.0.0.1:8000/accounts/login/ |
登录页 |
http://127.0.0.1:8000/register/ |
注册页 |
http://127.0.0.1:8000/admin/ |
Django Admin 后台 |
5. 数据库设计
5.1 数据库配置
| 配置项 | 值 |
|---|---|
| 引擎 | MySQL (django.db.backends.mysql) |
| 数据库名 | design_133_city |
| 用户 | root |
| 主机 | localhost:3306 |
| 字符集 | utf8mb4 |
| SQL 模式 | STRICT_TRANS_TABLES |
5.2 数据表概览
| 数据表 | 模型 | 说明 |
|---|---|---|
cost_of_living_records |
CostOfLivingRecord |
城市生活成本记录(主表) |
user_favorites |
UserFavorite |
用户收藏关联表 |
auth_user |
Django 内置 | 用户账号表 |
django_session |
Django 内置 | 会话表 |
5.3 CostOfLivingRecord 模型
表名:cost_of_living_records
元数据字段
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id |
BigAutoField | PK, 自增 | 主键 |
city |
CharField(120) | 索引, 非空 | 城市英文名 |
city_cn |
CharField(120) | 可空 | 城市中文名 |
country |
CharField(120) | 索引, 非空 | 国家英文名 |
country_cn |
CharField(120) | 可空 | 国家中文名 |
created_at |
DateTimeField | auto_now_add | 创建时间 |
updated_at |
DateTimeField | auto_now | 更新时间 |
餐饮类指标(14 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
cheap_meal |
廉价餐厅 | USD |
mid_range_meal |
2人中档餐厅三道菜 | USD |
mcdonalds_meal |
麦当劳套餐 | USD |
domestic_beer_restaurant |
国产啤酒-餐馆 | USD |
imported_beer_restaurant |
进口啤酒-餐馆 | USD |
cappuccino |
卡布奇诺 | USD |
coke |
可乐 | USD |
water_small |
瓶装水 0.33L | USD |
milk |
牛奶 1L | USD |
white_bread |
白面包 500g | USD |
rice |
大米 1kg | USD |
eggs |
鸡蛋 12 个 | USD |
local_cheese |
当地奶酪 1kg | USD |
chicken_fillet |
鸡肉片 1kg | USD |
日用品类指标(10 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
beef_round |
牛圆肉 1kg | USD |
apples |
苹果 1kg | USD |
bananas |
香蕉 1kg | USD |
oranges |
橙子 1kg | USD |
tomatoes |
番茄 1kg | USD |
potatoes |
马铃薯 1kg | USD |
onions |
洋葱 1kg | USD |
lettuce |
莴苣 1 头 | USD |
water_large |
瓶装水 1.5L | USD |
wine |
中档葡萄酒 | USD |
酒类与烟草(3 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
domestic_beer_market |
国产啤酒-市场 | USD |
imported_beer_market |
进口啤酒-市场 | USD |
cigarettes |
万宝路 20 支 | USD |
交通类指标(8 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
one_way_ticket |
公共交通单程票 | USD |
monthly_pass |
公共交通月票 | USD |
taxi_start |
出租车起步价 | USD |
taxi_1km |
出租车 1 公里 | USD |
taxi_waiting_hour |
出租车等待 1 小时 | USD |
gasoline |
汽油 1L | USD |
volkswagen_golf |
大众高尔夫 | USD |
toyota_corolla |
丰田卡罗拉 | USD |
通信与生活服务(6 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
basic_utilities |
85 平方米公寓基础开销 | USD/月 |
mobile_tariff |
1 分钟手机费 | USD |
internet |
互联网 60Mbps | USD/月 |
fitness_club |
健身俱乐部月费 | USD |
tennis_court |
网球场周末 1 小时 | USD |
cinema |
电影院票价 | USD |
教育类指标(2 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
preschool |
私立学前班月费 | USD |
international_primary_school |
国际小学年费 | USD |
服饰类指标(4 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
jeans |
牛仔裤 | USD |
summer_dress |
夏装 | USD |
nike_shoes |
耐克跑步鞋 | USD |
leather_shoes |
男士皮鞋 | USD |
住房类指标(6 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
apartment_1br_center |
市中心 1 居室月租 | USD |
apartment_1br_outside |
市中心外 1 居室月租 | USD |
apartment_3br_center |
市中心 3 居室月租 | USD |
apartment_3br_outside |
市中心外 3 居室月租 | USD |
price_sqm_center |
市中心公寓每平方米购买价 | USD |
price_sqm_outside |
市中心外公寓每平方米购买价 | USD |
收入与金融(2 个字段)
| 字段 | 中文标签 | 单位 |
|---|---|---|
salary |
平均月净工资 | USD |
mortgage_rate |
年度抵押贷款利率 | % |
质量标记(1 个字段)
| 字段 | 中文标签 | 说明 |
|---|---|---|
data_quality_score |
数据质量标记 | Numbeo 提供的数据可信度评分 |
数据库索引
| 索引名称 | 字段 | 说明 |
|---|---|---|
| 主键索引 | id |
自增主键 |
| 普通索引 | country, city |
国家+城市联合查询 |
| 普通索引 | salary |
工资排序/筛选 |
| 普通索引 | apartment_1br_center |
租金排序/筛选 |
模型属性
python
@property
def data_completeness(self):
"""返回 14 个关键字段的完整度百分比 (0-100)"""
5.4 UserFavorite 模型
表名:user_favorites
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id |
BigAutoField | PK | 主键 |
user |
ForeignKey(User) | CASCADE | 关联用户 |
record |
ForeignKey(CostOfLivingRecord) | CASCADE | 关联城市记录 |
created_at |
DateTimeField | auto_now_add | 收藏时间 |
约束 :(user, record) 唯一联合约束,防止重复收藏。
5.5 ER 关系图
┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐
│ auth_user │ │ cost_of_living_ │ │ user_favorites│
│──────────────│ │ records │ │──────────────│
│ id (PK) │◄──┐ │─────────────────────│ ┌──►│ id (PK) │
│ username │ │ │ id (PK) │ │ │ user_id (FK) │
│ password │ └───│ ... │◄──┘ │ record_id(FK)│
│ email │ │ city, country │ │ created_at │
│ ... │ │ 57 项指标字段 │ └──────────────┘
└──────────────┘ │ created_at, updated_at│
└─────────────────────┘
6. 后端架构
6.1 URL 路由体系
根路由 (citycost/urls.py)
| URL 模式 | 目标 | 说明 |
|---|---|---|
admin/ |
admin.site.urls |
Django Admin 后台 |
accounts/ |
django.contrib.auth.urls |
内置认证(登录/登出/密码重置) |
| `` (根路径) | include("dashboard.urls") |
应用路由 |
应用路由 (dashboard/urls.py)
共 40 条 URL 规则,分为四类:
用户页面(3 条)
| URL | 视图 | 说明 |
|---|---|---|
register/ |
register |
用户注册 |
profile/ |
profile |
个人中心 |
| `` | index |
首页看板 |
数据 CRUD(7 条)
| URL | 视图 | 说明 |
|---|---|---|
records/ |
record_list |
数据列表 |
records/export/ |
record_export |
CSV 导出 |
records/import/ |
record_import |
CSV 导入 |
records/new/ |
record_create |
新增记录 |
records/<pk>/ |
record_detail |
记录详情 |
records/<pk>/edit/ |
record_update |
编辑记录 |
records/<pk>/delete/ |
record_delete |
删除记录 |
分析页面(7 条)
| URL | 视图 | 说明 |
|---|---|---|
analysis/predict/ |
predict |
租金预测 |
analysis/city-compare/ |
city_compare |
城市对比 |
analysis/purchasing-power/ |
purchasing_power |
购买力分析 |
analysis/distribution/ |
distribution |
分布分析 |
analysis/regional/ |
regional |
区域分析 |
analysis/cost-structure/ |
cost_structure |
成本结构 |
analysis/affordability/ |
affordability_ranking |
负担力排名 |
API 接口(15 条)
详见 [第 9 章 API 接口文档](#第 9 章 API 接口文档)。
6.2 视图层设计
所有视图均为函数视图(FBV),除 register 外均使用 @login_required 装饰器。
辅助函数
| 函数 | 说明 |
|---|---|
_round(value, digits=2) |
浮点数四舍五入 |
_avg(field) |
计算字段全局均值 |
_metric_from_request(request) |
从 GET 参数提取并验证指标键 |
_field_label(field_name) |
获取字段的中文 verbose_name |
_group_values(record) |
构建详情页分组数据 |
_prediction_defaults() |
计算预测表单默认值 |
_category_baselines() |
计算分类基线均值 |
_category_index(row, fields, baselines) |
计算成本指数 |
_country_rows(fields) |
国家级聚合查询 |
_monthly_essential(row) |
计算月度基本开支 |
_recommend_cities(limit=8) |
按工资/开支比推荐城市 |
_train_rent_model() |
训练租金预测模型 |
6.3 表单设计
BootstrapMixin
为所有表单字段自动添加 Bootstrap CSS 类:
- 文本输入类字段 →
form-control - 选择框类字段 →
form-select
RegisterForm
基于 Django UserCreationForm,新增必填 email 字段。
RecordForm
基于 CostOfLivingRecord 模型,排除 created_at 和 updated_at,所有数值字段添加 step="0.01" 属性。
PredictionForm
6 个浮点数输入字段(salary, basic_utilities, internet, cheap_meal, price_sqm_center, gasoline),默认值从数据库均值动态计算。
6.4 认证与权限
- 使用 Django 内置认证系统 (
django.contrib.auth) - 未登录用户自动重定向到
/accounts/login/ - 注册成功后自动登录
- 密码校验已简化:仅保留最低长度 1 位的要求
- 登录/注册页面使用城市天际线背景图 + 毛玻璃效果
7. 前端架构
7.1 模板继承体系
base.html
├── login.html
├── register.html
├── index.html
├── profile.html
├── record_list.html
├── record_detail.html
├── record_form.html
├── record_confirm_delete.html
├── record_import.html
├── predict.html
├── city_compare.html
├── purchasing_power.html
├── distribution.html
├── regional.html
├── cost_structure.html
└── affordability.html
base.html 提供两种布局模式:
- 已认证用户:左侧 260px 固定侧边栏 + 右侧主内容区
- 未认证用户 :全屏居中认证面板(
auth_content块)
7.2 设计系统 (app.css)
CSS 自定义属性
css
:root {
--ink: #1a1d29; /* 主文字色 */
--muted: #6b7280; /* 次要文字色 */
--line: #e5e7eb; /* 边框线色 */
--surface: #ffffff; /* 卡片背景色 */
--page: #f0f2f5; /* 页面背景色 */
--teal: #0d9488; /* 绿色强调 */
--blue: #2563eb; /* 蓝色主色 */
--gold: #f59e0b; /* 金色 */
--rose: #e11d48; /* 红色警告 */
--indigo: #6366f1; /* 靛蓝主色 */
--cyan: #0891b2; /* 青色 */
--radius: 12px; /* 圆角 */
--radius-sm: 8px; /* 小圆角 */
--radius-lg: 16px; /* 大圆角 */
--font: "Inter", "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
}
响应式断点
| 断点 | 宽度 | 适配 |
|---|---|---|
| 桌面端 | > 1180px | 4 列网格,完整侧边栏 |
| 平板端 | 820px - 1180px | 2 列网格 |
| 移动端 | < 820px | 侧边栏折叠为顶栏 |
| 小屏手机 | < 560px | 单列布局 |
特殊效果
- 登录/注册背景:城市天际线图片 + 半透明暗色遮罩 + 毛玻璃卡片
- 卡片悬停:顶部渐变色条显示 + 微向上位移 + 阴影增强
- 渐入动画 :
fadeInUp0.3s 缓动 - 减少动效 :
prefers-reduced-motion媒体查询支持
7.3 JavaScript 架构
所有 JS 文件采用 IIFE(立即执行函数表达式)模式,通过 window.addEventListener("DOMContentLoaded", init) 初始化。
公共模式
javascript
// API 请求封装
async function fetchJson(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(res.status);
return res.json();
}
// 统一 Tooltip 样式
function tooltipStyle() {
return {
backgroundColor: "rgba(15,23,42,0.9)",
borderColor: "rgba(99,102,241,0.2)",
textStyle: { color: "#fff", fontSize: 12 },
borderWidth: 1,
padding: [8, 12],
extraCssText: "border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.15);"
};
}
// 金额格式化
function money(v) {
return v != null ? "$" + Number(v).toLocaleString("en-US", {
minimumFractionDigits: 0, maximumFractionDigits: 0
}) : "-";
}
JS 文件职责
| 文件 | 行数 | 图表类型 | 对应 API |
|---|---|---|---|
charts.js |
273 | 仪表盘、柱状图、热力图、雷达图、散点图 | rankings, radar, scatter, affordability, category_heatmap, country_compare |
city_compare.js |
109 | 雷达图、柱状图、对比表格 | city_compare_data |
purchasing_power.js |
87 | 水平柱状图 | purchasing_power |
distribution.js |
106 | 直方图 + 标记线 | distribution |
regional.js |
91 | 柱状图、详情表格 | regional |
cost_structure.js |
89 | 饼图、柱状图、详情表格 | cost_structure |
affordability.js |
124 | 3 组柱状图、排名表格 | affordability_ranking |
8. 功能模块详解
8.1 数据看板 (index)
首页提供全局数据概览,包含以下组件:
6 张统计摘要卡片
| 卡片 | 数据来源 | 说明 |
|---|---|---|
| 覆盖城市数 | COUNT(DISTINCT city) |
数据集中的城市总数 |
| 覆盖国家数 | COUNT(DISTINCT country) |
数据集中的国家总数 |
| 全球平均工资 | AVG(salary) |
全球月均净工资 |
| 全球平均租金 | AVG(apartment_1br_center) |
市中心一居室月租均值 |
| 全球平均餐饮 | AVG(cheap_meal) |
廉价餐厅均值 |
| 全球平均房价 | AVG(price_sqm_center) |
市中心每平方米房价均值 |
6 组可视化图表
- 国家排名柱状图:按选定指标展示 Top 12 国家
- 城市雷达图:单城市 5 维度与全球均值对比(餐饮、交通、住房、通信娱乐、教育服饰)
- 工资 vs 租金散点图:最多 900 个城市的工资-租金关系
- 负担力仪表盘:全球平均工资覆盖率
- 分类热力图:Top 16 国家 × 5 大类别的成本指数矩阵
- 国家对比雷达图:默认 5 国多维对比
城市推荐卡片
基于 工资 / (房租 + 水电网 + 餐饮 × 30 + 交通) 比率排名,展示 Top 8 最宜居城市。
8.2 数据管理
列表页 (record_list)
- 分页:每页 20 条
- 搜索:按城市名模糊搜索(中英文)
- 筛选:按国家下拉筛选
- 排序:支持按城市、国家、工资、租金排序
- 收藏:每行可切换收藏状态
详情页 (record_detail)
- 5 张摘要卡片(工资、租金、餐饮、房价、数据完整度)
- 4 组指标分组展示:
- 餐饮日用品(12 项)
- 交通服务(8 项)
- 住房收入(9 项)
- 教育娱乐服饰(9 项)
- 收藏切换按钮
CSV 导入 (record_import)
- 支持上传 CSV 文件
- 自动映射中文列头到英文字段
- 按
city + country唯一键执行update_or_create - 缺失值用国家均值填充,其次用全局均值填充
CSV 导出 (record_export)
- 导出 10 列核心字段
- UTF-8 BOM 编码(兼容 Excel 中文显示)
8.3 城市对比 (city_compare)
- 选择 2-5 个城市进行对比
- 雷达图:5 维度标准化对比
- 柱状图:各维度原始值对比
- 对比表格:详细数值列表
8.4 购买力分析 (purchasing_power)
- 按国家选择
- 计算月工资可购买的 17 种日常商品数量
- 水平柱状图展示购买力排名
- 摘要卡片展示平均购买力指标
8.5 分布分析 (distribution)
- 选择任意指标
- 直方图展示全球分布
- 8 项描述性统计:
- 样本量、均值、中位数、标准差
- 最小值、最大值、Q1(25%)、Q3(75%)
8.6 区域分析 (regional)
- 按 6 大洲分组:亚洲、北美洲、南美洲、欧洲、大洋洲、非洲
- 柱状图展示各区域均值
- 详情表格展示每个区域的均值、最小值、最大值、城市数
8.7 成本结构 (cost_structure)
- 按国家选择
- 6 大类别的成本占比:
- 餐饮(廉价餐厅 + 中档餐厅 + 咖啡 + 可乐)
- 日用品(牛奶 + 面包 + 大米 + 鸡蛋 + 鸡肉)
- 交通(单程票 + 月票 + 出租车 + 汽油)
- 住房(1 居室租金 + 水电网)
- 娱乐(健身 + 电影 + 网球)
- 服饰(牛仔裤 + 夏装 + 运动鞋 + 皮鞋)
- 饼图 + 柱状图 + 详情表格
8.8 负担力排名 (affordability_ranking)
3 组图表:
- 工资覆盖率排名 :
工资 / 基本开支 × 100% - 租金压力排名 :
租金 / 工资 × 100% - 食品开支占比排名 :
食品开支 / 工资 × 100%
完整排名表格包含:国家、覆盖率、租金占比、食品占比、平均工资、平均租金、平均餐饮开支。
9. API 接口文档
所有 API 返回 JSON 格式,均需要登录认证。
9.1 全局概览
GET /api/overview/
响应示例:
json
{
"cities": 5428,
"countries": 98,
"avg_salary": 1523.45,
"avg_rent": 856.32,
"avg_meal": 8.67,
"avg_home_price": 3245.12
}
9.2 国家地图数据
GET /api/country-map/?metric={metric_key}
参数: metric - 指标键(rent | rent_outside | home_price | salary | meal | transport)
响应示例:
json
{
"metric": "salary",
"label": "平均月净工资",
"rows": [
{"country": "Switzerland", "country_cn": "瑞士", "value": 6523.0, "cities": 5}
]
}
9.3 国家排名
GET /api/rankings/?metric={metric_key}
响应: Top 12 国家按选定指标降序排列。
9.4 城市雷达图
GET /api/radar/?city={city_name}
响应: 5 维度值与全局均值对比。
9.5 工资-租金散点
GET /api/scatter/
响应: 最多 900 个城市的 {salary, rent, city} 数组。
9.6 负担力概览
GET /api/affordability/
响应: 全局覆盖率、Top 10 高覆盖率国家、租金压力 Top 10。
9.7 分类热力图
GET /api/category-heatmap/?metric={metric_key}
响应: Top 16 国家 × 5 类别的成本指数矩阵。
9.8 国家对比
GET /api/country-compare/?countries=China,United States,Germany
参数: countries - 逗号分隔的 2-5 个国家名。
响应: 雷达图数据 + 柱状图数据 + 国家卡片信息。
9.9 城市对比
GET /api/city-compare/?cities=Tokyo,Shanghai,New York
参数: cities - 逗号分隔的 2-5 个城市名。
响应: 雷达图数据 + 柱状图数据 + 对比表格数据。
9.10 购买力分析
GET /api/purchasing-power/?country={country_name}
响应: 17 种商品的可购买数量。
9.11 分布分析
GET /api/distribution/?metric={metric_key}
响应: 直方图分箱数据 + 描述性统计。
9.12 区域分析
GET /api/regional/?metric={metric_key}
响应: 6 大洲的聚合统计。
9.13 成本结构
GET /api/cost-structure/?country={country_name}
响应: 6 大类别的成本值和百分比。
9.14 负担力排名
GET /api/affordability-ranking/
响应: 全部国家的覆盖率、租金占比、食品占比排名。
9.15 收藏切换
POST /api/favorite-toggle/
Content-Type: application/x-www-form-urlencoded
record_id={id}
响应:
json
{"favorited": true}
10. 机器学习模块
10.1 模型概述
系统内置一个基于 scikit-learn 的线性回归模型,用于预测城市市中心一居室月租。
10.2 算法详情
| 项目 | 说明 |
|---|---|
| 算法 | sklearn.linear_model.LinearRegression |
| 目标变量 | apartment_1br_center(市中心一居室月租,USD) |
| 特征变量 | salary(工资)、basic_utilities(基础开销)、internet(网络)、cheap_meal(廉价餐饮)、price_sqm_center(市中心房价)、gasoline(汽油) |
| 训练数据 | 数据库中所有 7 个字段均非空的记录 |
| 最小样本量 | 10 条记录 |
| 输出 | 预测租金值、R² 决定系数、各特征系数 |
10.3 使用流程
- 用户在预测页面输入 6 项特征值(或使用数据库均值作为默认值)
- 后端从数据库加载训练数据
- 训练线性回归模型
- 返回预测值、R² 分数和各特征系数
- 前端展示预测结果和模型解释
10.4 模型代码
python
def _train_rent_model():
"""训练租金预测模型"""
qs = CostOfLivingRecord.objects.filter(
apartment_1br_center__isnull=False,
salary__isnull=False,
basic_utilities__isnull=False,
internet__isnull=False,
cheap_meal__isnull=False,
price_sqm_center__isnull=False,
gasoline__isnull=False,
)
if qs.count() < 10:
raise RuntimeError("可用训练数据不足")
df = pd.DataFrame(qs.values(FEATURE_FIELDS + ["apartment_1br_center"]))
X = df[FEATURE_FIELDS]
y = df["apartment_1br_center"]
model = LinearRegression()
model.fit(X, y)
return model, model.score(X, y)
11. 数据导入与管理
11.1 管理命令一览
| 命令 | 文件 | 说明 |
|---|---|---|
import_cost_data |
import_cost_data.py |
导入 Numbeo CSV 数据 |
create_admin |
create_admin.py |
创建/重置管理员账号 |
populate_chinese_names |
populate_chinese_names.py |
填充中文城市/国家名 |
11.2 数据导入 (import_cost_data)
bash
python manage.py import_cost_data [--path PATH] [--encoding ENCODING] [--append]
| 参数 | 默认值 | 说明 |
|---|---|---|
--path |
cost-of-living_20221203.csv |
CSV 文件路径 |
--encoding |
gb18030 |
文件编码 |
--append |
False | 追加模式(默认清空后导入) |
处理流程:
- 使用 pandas 读取 CSV 文件
- 将 63 列中文列头映射为 57 个英文字段名
- 对缺失值:先用同国家均值填充,再用全局均值填充
- 使用
bulk_create批量插入,每批 500 条
11.3 中文名填充 (populate_chinese_names)
bash
python manage.py populate_chinese_names
内置约 190 个国家和 4956 个城市的中文名称映射,通过音译规则自动生成。对于未匹配的城市,使用基于音节的规则引擎进行自动翻译。
音译引擎组成:
MANUAL字典:约 300 个主要城市的手动映射WORD_PATTERNS:约 50 个常见词汇翻译(如 "north" → "北")SYLLABLE_RULES:约 100+ 个音节到中文的映射规则SUFFIX_PATTERNS:约 30 个常见后缀(如 "ton" → "顿","burg" → "堡")
12. 配置说明
12.1 核心配置项 (settings.py)
| 配置项 | 值 | 说明 |
|---|---|---|
DEBUG |
True |
开发模式(生产环境需改为 False) |
ALLOWED_HOSTS |
["localhost", "127.0.0.1"] |
允许的主机名 |
LANGUAGE_CODE |
zh-hans |
中文简体 |
TIME_ZONE |
Asia/Shanghai |
时区 |
LOGIN_URL |
login |
登录页 URL |
LOGIN_REDIRECT_URL |
dashboard:index |
登录后跳转 |
LOGOUT_REDIRECT_URL |
login |
登出后跳转 |
DEFAULT_AUTO_FIELD |
BigAutoField |
默认主键类型 |
12.2 密码策略
python
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {"min_length": 1},
},
]
当前仅要求密码长度 ≥ 1 位,已移除复杂度校验。
12.3 SimpleUI Admin 配置
python
SIMPLEUI_CONFIG = {
"system_keep": False,
"menus": [
{
"name": "生活成本数据",
"icon": "bi bi-database",
"models": [
{"name": "城市成本记录", "url": "/admin/dashboard/costoflivingrecord/"},
{"name": "用户收藏", "url": "/admin/dashboard/userfavorite/"},
],
},
{
"name": "账号权限",
"icon": "bi bi-shield-lock",
"models": [
{"name": "用户", "url": "/admin/auth/user/"},
{"name": "用户组", "url": "/admin/auth/group/"},
],
},
],
}
12.4 依赖清单
Django==4.2.8
django-simpleui
mysqlclient==2.2.0
PyMySQL==1.1.1
pandas==2.2.3
scikit-learn==1.3.2
文档版本 :v1.0
最后更新 :2026-05-22
适用系统版本:全球城市生活成本数据可视化分析系统 v1.0