Skip to content

第一站练习答案 ​

返回纵览 | 专题一 | 专题二

参考实现 ​

python
# tickets/views.py
import django
from django.http import JsonResponse
from django.views.decorators.http import require_GET


@require_GET
def health(request):
    return JsonResponse(
        {"status": "ok", "service": "ticket-desk", "django": django.get_version()}
    )
python
# tickets/tests.py
from django.test import TestCase
from django.urls import reverse


class HealthTests(TestCase):
    def test_health_contract(self):
        response = self.client.get(reverse("health"))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["status"], "ok")
        self.assertEqual(response.json()["service"], "ticket-desk")

    def test_health_rejects_post(self):
        self.assertEqual(self.client.post(reverse("health")).status_code, 405)

运行:

bash
python manage.py test tickets.tests.HealthTests

为什么不返回 settings ​

settings 可能包含数据库地址、密钥、内部主机名和功能开关。健康接口只公开调用方需要的稳定合同;详细依赖状态放到受保护的内部就绪端点或监控系统。

专题二核对 ​

  • ALLOWED_HOSTS = [host for host in os.environ["DJANGO_ALLOWED_HOSTS"].split(",") if host],随后在生产配置中为空就抛出 ImproperlyConfigured。
  • 一次性导入放到 tickets/management/commands/import_tickets.py,在 handle() 内执行并让重复运行可识别。
  • 用 CaptureQueriesContext(connection) 包住 importlib.import_module("tickets.apps"),断言查询数为零;不要在 AppConfig.ready() 做查询。

深水边界 ​

测试客户端绕过真实网络服务器,因此它证明 Django 合同,不证明代理、TLS 或进程信号。第十站还会补生产探测。

开放练习(不提供答案) ​

让 /ready/ 检查一次数据库连接,同时设置严格超时并避免在数据库故障时阻塞所有探针。记录 /health/ 与 /ready/ 的不同责任。

继续第二站

加码题解:请求链路与配置边界 ​

python
def parse_hosts(raw):
    hosts = [part.strip() for part in raw.split(',') if part.strip()]
    if not hosts:
        raise RuntimeError('production hosts required')
    return hosts

关键推理 ​

启动时把字符串环境变量转换成稳定列表,并在生产配置缺失时 fail fast。

可替代方案 ​

大型部署可从 secret manager 注入并在 management command 中运行 check --deploy。

典型错误 ​

在 AppConfig.ready 中访问数据库或启动线程,导致测试和迁移出现隐藏副作用。

复盘时请把状态码/事务/权限/资源清理中的至少一项写成自动化测试,而不是只截图成功页面。

用心记录每一步成长