全球城市生活成本数据可视化分析系统 - 技术文档
目录
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 安装步骤
# 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 |
| 邮箱 | [email protected] |
注意:
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 | 租金排序/筛选 |
模型属性
@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 接口文档。
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 自定义属性
: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) 初始化。
公共模式
// 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/
响应示例:
{
"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)
响应示例:
{
"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}
响应:
{"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 模型代码
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)
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)
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 密码策略
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {"min_length": 1},
},
]
当前仅要求密码长度 ≥ 1 位,已移除复杂度校验。
12.3 SimpleUI Admin 配置
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
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/qq_53846367/article/details/161324968



