全球城市生活成本数据可视化分析系统 - 技术文档
目录
1. 项目概述
1.1 系统简介
本系统是一个基于 Django 框架的全球城市生活成本数据可视化分析平台,旨在为用户提供全球主要城市的生活成本数据查询、对比分析和可视化展示。系统基于 Numbeo 公开数据集,涵盖全球 5000+ 城市的 57 项生活成本指标,包括餐饮、交通、住房、教育、娱乐等多个维度。
1.2 核心功能
| |
|---|
| 全局统计概览、国家排名、雷达图、散点图、热力图、城市推荐 |
| |
| |
| |
| 各指标的直方图分布 + 描述性统计(均值、中位数、标准差、四分位数) |
| |
| 各国生活成本的六大类别占比分析(饼图 + 柱状图) |
| |
| |
1.3 数据来源
数据集来源于 Numbeo,采集时间为 2022 年 12 月 3 日,包含 63 列数据(其中 57 项为数值型生活成本指标),编码格式为 GB18030。




























2. 技术栈
2.1 后端
2.2 前端
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 系统要求
4.2 安装步骤
# 1. 克隆或解压项目cd city# 2. 创建虚拟环境(推荐)python -m venv venvsource venv/bin/activate # Linux/Mac# venv\Scripts\activate # Windows# 3. 安装 Python 依赖pip install -r requirements.txt# 4. 创建 MySQL 数据库mysql -u root -pCREATE 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/ | |
5. 数据库设计
5.1 数据库配置
| |
|---|
| MySQL (django.db.backends.mysql) |
| design_133_city |
| root |
| localhost:3306 |
| utf8mb4 |
| STRICT_TRANS_TABLES |
5.2 数据表概览
| | |
|---|
cost_of_living_records | CostOfLivingRecord | |
user_favorites | UserFavorite | |
auth_user | | |
django_session | | |
5.3 CostOfLivingRecord 模型
表名:cost_of_living_records
元数据字段
| | | |
|---|
id | | | |
city | | | |
city_cn | | | |
country | | | |
country_cn | | | |
created_at | | | |
updated_at | | | |
餐饮类指标(14 个字段)
| | |
|---|
cheap_meal | | |
mid_range_meal | | |
mcdonalds_meal | | |
domestic_beer_restaurant | | |
imported_beer_restaurant | | |
cappuccino | | |
coke | | |
water_small | | |
milk | | |
white_bread | | |
rice | | |
eggs | | |
local_cheese | | |
chicken_fillet | | |
日用品类指标(10 个字段)
| | |
|---|
beef_round | | |
apples | | |
bananas | | |
oranges | | |
tomatoes | | |
potatoes | | |
onions | | |
lettuce | | |
water_large | | |
wine | | |
酒类与烟草(3 个字段)
| | |
|---|
domestic_beer_market | | |
imported_beer_market | | |
cigarettes | | |
交通类指标(8 个字段)
| | |
|---|
one_way_ticket | | |
monthly_pass | | |
taxi_start | | |
taxi_1km | | |
taxi_waiting_hour | | |
gasoline | | |
volkswagen_golf | | |
toyota_corolla | | |
通信与生活服务(6 个字段)
| | |
|---|
basic_utilities | | |
mobile_tariff | | |
internet | | |
fitness_club | | |
tennis_court | | |
cinema | | |
教育类指标(2 个字段)
| | |
|---|
preschool | | |
international_primary_school | | |
服饰类指标(4 个字段)
| | |
|---|
jeans | | |
summer_dress | | |
nike_shoes | | |
leather_shoes | | |
住房类指标(6 个字段)
| | |
|---|
apartment_1br_center | | |
apartment_1br_outside | | |
apartment_3br_center | | |
apartment_3br_outside | | |
price_sqm_center | | |
price_sqm_outside | | |
收入与金融(2 个字段)
质量标记(1 个字段)
数据库索引
| | |
|---|
| id | |
| country, city | |
| salary | |
| apartment_1br_center | |
模型属性
@propertydef data_completeness(self): """返回 14 个关键字段的完整度百分比 (0-100)"""
5.4 UserFavorite 模型
表名:user_favorites
| | | |
|---|
id | | | |
user | | | |
record | ForeignKey(CostOfLivingRecord) | | |
created_at | | | |
约束:(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)
| | |
|---|
admin/ | admin.site.urls | |
accounts/ | django.contrib.auth.urls | |
| include("dashboard.urls") | |
应用路由 (dashboard/urls.py)
共 40 条 URL 规则,分为四类:
用户页面(3 条)
| | |
|---|
register/ | register | |
profile/ | profile | |
| index | |
数据 CRUD(7 条)
| | |
|---|
records/ | record_list | |
records/export/ | record_export | |
records/import/ | record_import | |
records/new/ | record_create | |
records/<pk>/ | record_detail | |
records/<pk>/edit/ | record_update | |
records/<pk>/delete/ | record_delete | |
分析页面(7 条)
| | |
|---|
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) | |
_field_label(field_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 类:
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/ - 登录/注册页面使用城市天际线背景图 + 毛玻璃效果
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 提供两种布局模式:
- 已认证用户
- 未认证用户:全屏居中认证面板(
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;}
响应式断点
特殊效果
- 登录/注册背景:城市天际线图片 + 半透明暗色遮罩 + 毛玻璃卡片
- 卡片悬停
- 渐入动画
- 减少动效:
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 文件职责
| | | |
|---|
charts.js | | | rankings, radar, scatter, affordability, category_heatmap, country_compare |
city_compare.js | | | city_compare_data |
purchasing_power.js | | | purchasing_power |
distribution.js | | | distribution |
regional.js | | | regional |
cost_structure.js | | | cost_structure |
affordability.js | | | 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 组可视化图表
- 国家排名柱状图
- 城市雷达图:单城市 5 维度与全球均值对比(餐饮、交通、住房、通信娱乐、教育服饰)
- 工资 vs 租金散点图
- 负担力仪表盘
- 分类热力图:Top 16 国家 × 5 大类别的成本指数矩阵
- 国家对比雷达图
城市推荐卡片
基于 工资 / (房租 + 水电网 + 餐饮 × 30 + 交通) 比率排名,展示 Top 8 最宜居城市。
8.2 数据管理
列表页 (record_list)
详情页 (record_detail)
- 5 张摘要卡片(工资、租金、餐饮、房价、数据完整度)
CSV 导入 (record_import)
- 按
city + country 唯一键执行 update_or_create
CSV 导出 (record_export)
- UTF-8 BOM 编码(兼容 Excel 中文显示)
8.3 城市对比 (city_compare)
8.4 购买力分析 (purchasing_power)
8.5 分布分析 (distribution)
8.6 区域分析 (regional)
- 按 6 大洲分组:亚洲、北美洲、南美洲、欧洲、大洋洲、非洲
- 详情表格展示每个区域的均值、最小值、最大值、城市数
8.7 成本结构 (cost_structure)
- 餐饮(廉价餐厅 + 中档餐厅 + 咖啡 + 可乐)
- 日用品(牛奶 + 面包 + 大米 + 鸡蛋 + 鸡肉)
8.8 负担力排名 (affordability_ranking)
3 组图表:
- 工资覆盖率排名
- 租金压力排名
- 食品开支占比排名
完整排名表格包含:国家、覆盖率、租金占比、食品占比、平均工资、平均租金、平均餐饮开支。
9. API 接口文档
所有 API 返回 JSON 格式,均需要登录认证。
9.1 全局概览
响应示例:
{ "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 工资-租金散点
响应: 最多 900 个城市的 {salary, rent, city} 数组。
9.6 负担力概览
响应: 全局覆盖率、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-urlencodedrecord_id={id}
响应:
10. 机器学习模块
10.1 模型概述
系统内置一个基于 scikit-learn 的线性回归模型,用于预测城市市中心一居室月租。
10.2 算法详情
| |
|---|
| sklearn.linear_model.LinearRegression |
| apartment_1br_center |
| salary(工资)、basic_utilities(基础开销)、internet(网络)、cheap_meal(廉价餐饮)、price_sqm_center(市中心房价)、gasoline(汽油) |
| |
| |
| |
10.3 使用流程
- 用户在预测页面输入 6 项特征值(或使用数据库均值作为默认值)
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 | |
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 | |
--encoding | gb18030 | |
--append | | |
处理流程:
- 使用
bulk_create 批量插入,每批 500 条
11.3 中文名填充 (populate_chinese_names)
python manage.py populate_chinese_names
内置约 190 个国家和 4956 个城市的中文名称映射,通过音译规则自动生成。对于未匹配的城市,使用基于音节的规则引擎进行自动翻译。
音译引擎组成:
MANUALWORD_PATTERNS:约 50 个常见词汇翻译(如 “north” → “北”)SYLLABLE_RULESSUFFIX_PATTERNS:约 30 个常见后缀(如 “ton” → “顿”,“burg” → “堡”)
12. 配置说明
12.1 核心配置项 (settings.py)
| | |
|---|
DEBUG | True | |
ALLOWED_HOSTS | ["localhost", "127.0.0.1"] | |
LANGUAGE_CODE | zh-hans | |
TIME_ZONE | Asia/Shanghai | |
LOGIN_URL | login | |
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.8django-simpleuimysqlclient==2.2.0PyMySQL==1.1.1pandas==2.2.3scikit-learn==1.3.2
文档版本:v1.0最后更新:2026-05-22适用系统版本:全球城市生活成本数据可视化分析系统 v1.0