HR Observer
观察HR · 连接人才 · 探索未来工作
Observing HR. Connecting Talent. Exploring the Future of Work.
项目简介
HR Observer 是一个面向 CHRO/HRD/TA 负责人及中高端 HR 从业者的专业媒体平台,专注于 AI 时代的人力资源行业观察、HR Leader 深度访谈、AI × HR 前沿探索与人才趋势分析。
核心定位
- 专业内容媒体:深度洞察与行业分析,而非新闻搬运
- HR Leader Network:建立 100+ 高质量 HR Leader 人物档案与访谈
- AI × HR 知识平台:追踪 AI Recruiting、HR Agent、Talent Intelligence 等前沿
- 人才趋势观察平台:AI 人才流动、薪资趋势、技术人才地图
品牌理念
不是报道 HR 发生了什么,而是帮助 HR 理解,接下来会发生什么。
功能特性
内容栏目
| 栏目 | 说明 | URL |
|---|---|---|
| 访谈 | HR Leader 深度访谈,采用统一访谈框架 | /interviews/ |
| 洞察 | 行业深度洞察,解释趋势而非新闻 | /insights/ |
| AI × HR | AI 与 HR 前沿,涵盖 AI Recruiting、HR Agent、Talent Intelligence | /ai-hr/ |
| 观点 | 主理人 Michael Song 的一线观察与独立判断 | /opinions/ |
| 工具评测 | HR Observer Tested,真实测试 AI 工具/Agent | /tools/ |
| 人才趋势 | Talent Intelligence,AI 人才流动与未来趋势 | /talent/ |
核心功能
- 人物档案系统:HR Leader Directory,包含职业经历、核心领域、相关访谈
- 全文搜索:跨文章、人物的智能搜索,支持标签过滤
- 中英文双语:中文主内容 + 英文精选内容,一键切换
- Newsletter 订阅:HR Observer Weekly,每周一次读懂 HR、AI 与人才
- Django Admin CMS:内置内容管理系统,支持草稿、定时发布、状态管理
- 响应式设计:基于 Tailwind CSS,适配桌面与移动端
安全特性
- CSRF 保护全站 POST 请求
- Markdown 内容 XSS 防护(bleach 清洗)
- slug 唯一约束防止 URL 冲突
- 404 处理与自定义错误页面
技术栈
后端
- 框架:Django 5.x
- 数据库:SQLite(开发)/ PostgreSQL(生产)
- Markdown 渲染:markdown + bleach(XSS 防护)
- 图片处理:Pillow
前端
- 样式:Tailwind CSS 3.x(CDN)
- 交互:Alpine.js 3.x(CDN)
- 字体:Noto Sans SC(中文)、Inter(英文)、Georgia(标题)
- 图标:无外部图标库,纯 CSS 实现
开发工具
- 测试:Django TestCase + pytest-django
- 代码格式化:black + isort
- Lint:flake8
- 覆盖率:coverage.py
部署
- WSGI:Gunicorn
- 静态文件:Whitenoise
- 进程管理:systemd / supervisor
- 反向代理:Nginx
快速开始
环境要求
- Python 3.10 或更高版本
- pip 23.0 或更高版本
- Git
安装步骤
# 1. 克隆仓库
git clone https://github.com/your-org/hr-observer.git
cd hr-observer
# 2. 创建虚拟环境(推荐)
python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate
# 3. 安装依赖
pip install -r requirements.txt
# 4. 数据库迁移
python manage.py migrate
# 5. 生成演示数据(可选)
python manage.py seed_demo_data
# 6. 创建超级用户
python manage.py createsuperuser
# 7. 启动开发服务器
python manage.py runserver
访问应用
- 网站首页:http://127.0.0.1:8000/
- 管理后台:http://127.0.0.1:8000/admin/
- API 文档:暂无(V1 MVP 不提供 REST API)
文档
项目文档
| 文档 | 说明 |
|---|---|
| 设计文档 | 技术架构、数据模型、URL 设计、设计系统 |
| 规格文档 | EARS 格式的功能/非功能需求、验收标准 |
| 任务分解 | 8 阶段 59 个任务,含依赖关系与需求追溯 |
| 文档评审 | 三份文档的一致性检查与 PRD 对齐验证 |
Django 文档
开发指南
项目结构
hr-observer/
├── docs/ # 设计/规格/任务/评审文档
│ ├── design.md
│ ├── spec.md
│ ├── tasks.md
│ └── review.md
├── hr_observer/ # Django 项目配置
│ ├── settings.py # 核心配置
│ ├── urls.py # 主路由
│ └── wsgi.py
├── content/ # 内容应用
│ ├── models.py # Article 模型
│ ├── views.py # 首页、列表、详情视图
│ ├── urls.py
│ ├── admin.py
│ ├── markdown_utils.py # Markdown 渲染
│ ├── management/commands/ # 管理命令
│ └── migrations/
├── people/ # 人物应用
│ ├── models.py # Person 模型
│ ├── views.py # 人物列表、详情
│ └── migrations/
├── newsletter/ # 订阅应用
│ ├── models.py # Subscriber 模型
│ ├── views.py # 订阅、退订
│ └── migrations/
├── search/ # 搜索应用
│ ├── views.py # 跨模型搜索
│ └── migrations/
├── common/ # 公共应用
│ ├── models.py # Tag、SiteSetting
│ ├── views.py # 语言切换
│ ├── context_processors.py
│ ├── utils.py # 国际化字段选择
│ └── templatetags/ # 模板过滤器
├── templates/ # 全站模板
│ ├── base.html # 基础模板
│ ├── home.html # 首页
│ ├── content/ # 内容模板
│ ├── people/ # 人物模板
│ ├── newsletter/ # 订阅模板
│ ├── search/ # 搜索模板
│ └── partials/ # 可复用片段
├── static/ # 静态资源
│ ├── css/style.css # 自定义样式
│ └── js/
├── locale/ # 国际化翻译文件
├── tests.py # 集成测试
├── manage.py
├── requirements.txt
├── pyproject.toml
└── README.md
代码规范
# 格式化代码
black .
# 排序导入
isort .
# Lint 检查
flake8 .
测试
# 运行所有测试
python manage.py test
# 运行特定应用测试
python manage.py test content
# 运行特定测试类
python manage.py test content.tests.ArticleModelTest
# 生成覆盖率报告
coverage run manage.py test
coverage report
coverage html
管理命令
| 命令 | 说明 |
|---|---|
python manage.py seed_demo_data |
生成演示数据(10 标签、4 人物、6 文章、3 订阅者) |
python manage.py publish_scheduled |
发布定时文章(status=scheduled 且 published_at<=now) |
python manage.py export_subscribers |
导出活跃订阅者为 CSV |
python manage.py makemessages |
提取翻译字符串 |
python manage.py compilemessages |
编译翻译文件 |
添加新内容
- 登录后台:http://127.0.0.1:8000/admin/
- 创建标签:Common → Tags → 添加
- 创建人物:People → Persons → 添加(可关联标签)
- 创建文章:Content → Articles → 添加(选择栏目类型、关联人物、关联标签)
- 发布文章:将状态改为
已发布,设置发布时间
国际化(i18n)
# Python 代码
from django.utils.translation import gettext as _
message = _('欢迎')
# 模板
{% load i18n %}
{% trans "欢迎" %}
# 提取翻译字符串
python manage.py makemessages
# 编译翻译文件
python manage.py compilemessages
部署
生产环境配置
# hr_observer/settings.py
DEBUG = False
ALLOWED_HOSTS = ['your-domain.com', 'www.your-domain.com']
# 数据库(PostgreSQL)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'hr_observer',
'USER': 'your_user',
'PASSWORD': 'your_password',
'HOST': 'localhost',
'PORT': '5432',
}
}
# 静态文件
STATIC_ROOT = '/var/www/hr-observer/staticfiles/'
# 安全设置
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
部署步骤
# 1. 收集静态文件
python manage.py collectstatic
# 2. 使用 Gunicorn 启动
gunicorn hr_observer.wsgi:application --bind 0.0.0.0:8000
# 3. 使用 systemd 管理进程(示例)
# /etc/systemd/system/hr-observer.service
[Unit]
Description=HR Observer Django Application
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/hr-observer
Environment="PATH=/var/www/hr-observer/venv/bin"
ExecStart=/var/www/hr-observer/venv/bin/gunicorn \
--workers 3 \
--bind unix:/var/www/hr-observer/hr-observer.sock \
hr_observer.wsgi:application
[Install]
WantedBy=multi-user.target
Nginx 配置
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://unix:/var/www/hr-observer/hr-observer.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
alias /var/www/hr-observer/staticfiles/;
}
location /media/ {
alias /var/www/hr-observer/media/;
}
}
环境变量
创建 .env 文件(添加到 .gitignore):
SECRET_KEY=your-secret-key-here
DATABASE_URL=postgresql://user:password@localhost:5432/hr_observer
DEBUG=False
ALLOWED_HOSTS=your-domain.com,www.your-domain.com
常见问题
Q: 如何修改站点品牌信息?
A: 登录后台 → Common → Site Settings,修改品牌名称、标语、主理人信息等。
Q: 如何添加新的栏目类型?
A: 编辑 content/models.py 中的 Article.TYPE_CHOICES,添加新类型,然后运行 makemigrations 和 migrate。
Q: 如何自定义颜色?
A: 编辑 static/css/style.css 中的 CSS 变量,或修改 Tailwind 配置(templates/base.html 中的 tailwind.config)。
Q: Newsletter 如何发送邮件?
A: V1 MVP 仅管理订阅者列表,不集成邮件发送服务。可使用 export_subscribers 命令导出 CSV,导入到 Beehiiv/Substack/Mailchimp 等平台。
贡献
欢迎贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
贡献指南
- 遵循 PEP 8 代码规范
- 为新功能添加测试
- 更新相关文档
- 提交前运行
python manage.py test确保测试通过
详细贡献指南请参阅 CONTRIBUTING.md。
路线图
V1.0 MVP(当前)
- ✅ 首页 8 模块
- ✅ 6 栏目内容系统
- ✅ 人物档案
- ✅ Newsletter 订阅
- ✅ 全文搜索
- ✅ 中英文切换
- ✅ Django Admin CMS
V1.1(计划中)
- Newsletter 邮件发送集成
- 文章评论系统
- 用户注册登录
- 收藏与阅读历史
- 社交分享优化
V2.0(未来)
- HR Leader Directory 高级筛选
- AI HR Assistant 聊天机器人
- 人才数据可视化
- 行业研究报告生成
- HR Club 社区功能
许可证
本项目采用 MIT 许可证 - 详见 LICENSE 文件。
品牌与联系
HR Observer by Michael Song
Founder & Chief Talent Observer
Made with ❤️ by HR Observer Team
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hr_observer-0.1.1.tar.gz.
File metadata
- Download URL: hr_observer-0.1.1.tar.gz
- Upload date:
- Size: 67.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/4.0.2 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff23cb405ee30628179d2af053afa317e885f2611c776b23db8697335ffcc7e6
|
|
| MD5 |
719fbe9e5bfbdc8e60bd9b81ab25f6fa
|
|
| BLAKE2b-256 |
cb2fd733a56b482bd7a00a2bfa45ffe4bf70ffdeb998fa1107ed153019086481
|
File details
Details for the file hr_observer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: hr_observer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 46.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/4.0.2 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66c98d721cf25988d8654b749b8d298c860178342f1454f50f88255206d570fb
|
|
| MD5 |
e210b1516eca1613488ab2747fc0ec06
|
|
| BLAKE2b-256 |
e235d8f8f52583008773e70513763fa539d007d3ea8038d75525b272c07ba187
|