Django入门教程:搭建你的第一个Python网站

一人公司实验室
2025-12-14 02:50
阅读 340

上周五晚上十点半,我还在公司改一个医疗表单的校验逻辑。产品经理凌晨两点发来的微信消息还钉在聊天窗口顶部:“这个字段能不能加个实时提示?”——而我的 MacBook Pro 已经烫得能煎蛋了。

我是某医疗软件公司的 Python 开发,三年前从 Go 转过来写 Django,理由很朴素:公司主栈是 Python + Django,而我那会儿刚被“优化”出上一家搞云原生的小厂。虽然私下还是更爱 Go 的简洁和编译时安全感,但为了饭碗,Django 也慢慢成了我的主力武器。最近因为考虑跳槽(别问,问就是 PIP 面谈又没过),开始重新梳理基础,顺便把一些踩过的坑整理出来——于是就有了这篇面向新手的 Django 入门实战。

为什么不是 Flask?也不是 Go?

很多新人一上来就问:“为什么不直接用 Flask?轻量啊!” 或者 “Go 写 Web 不是更快吗?”

说实话,在我们这种医疗系统里,“快”从来不是第一优先级。稳定、可审计、有成熟生态支持才是命脉。Django 自带 admin、ORM、用户认证、CSRF 防护,这些在处理患者数据时简直是救命稻草。你敢信?去年双11期间我们系统崩了一次,根因居然是某个外包团队用裸 SQL 拼接参数导致注入漏洞——自那以后,老板勒令所有新项目必须用 Django ORM。

至于 Go,我确实怀念它那丝滑的并发模型和零依赖部署。但现实是:我们的前端同事只会 JavaScript,后端接口要是返回 protobuf 而不是 JSON,他们能当场罢工。而且,医疗行业对审计日志要求极高,Django 的信号(signals)机制配合 django-simple-history 插件,能自动记录每个字段的变更历史,Go 生态里要自己造轮子,成本太高。

所以,别纠结“最酷”的技术,先搞定“最稳”的方案。

动手!创建你的第一个 Django 站点

别被“网站”吓到。在 Django 里,一个“项目”(project)可以包含多个“应用”(app),比如 patient、billing、report。我们今天就建个极简的患者登记页。

# 假设你已装好 Python 3.9+ 和 pip
pip install django
django-admin startproject clinic_site
cd clinic_site
python manage.py startapp patients

然后在 clinic_site/settings.py 里注册这个 app:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    # ... 其他默认项
    'patients',  # ← 加这一行
]

接下来定义模型。医疗系统最怕数据不一致,所以我们用 Django ORM 强约束:

# patients/models.py
from django.db import models

class Patient(models.Model):
    GENDER_CHOICES = [('M', 'Male'), ('F', 'Female'), ('O', 'Other')]
    
    name = models.CharField(max_length=100)
    id_number = models.CharField(max_length=18, unique=True)  # 身份证号唯一
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
    birth_date = models.DateField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

跑迁移:

python manage.py makemigrations
python manage.py migrate

这时候如果你像我一样习惯用 Mac 开发,终端里敲命令飞快;但别忘了,测试还得切 Windows 虚拟机——上周就因为 Windows 上路径大小写敏感问题,测试同事追着我骂了半小时。

别只写后端!前端交互也很香

我知道,很多后端兄弟看到前端就头大。但既然我对动画和交互感兴趣(业余时间甚至偷偷学了 GSAP),这次干脆把前端也包了。

我们在 patients/views.py 里写个简单视图:

from django.shortcuts import render
from .models import Patient

def patient_list(request):
    patients = Patient.objects.all()
    return render(request, 'patients/list.html', {'patients': patients})

然后配路由:

# clinic_site/urls.py
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('patients/', include('patients.urls')),
]

# patients/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.patient_list, name='patient_list'),
]

模板 patients/templates/patients/list.html 用点简单的 JavaScript 做加载动画:

<div id="loading" style="display:none;">加载中...</div>
<ul id="patient-list"></ul>

<script>
fetch('/api/patients/')  // 假设有 API 接口
  .then(res => {
    document.getElementById('loading').style.display = 'block';
    return res.json();
  })
  .then(data => {
    const ul = document.getElementById('patient-list');
    data.forEach(p => {
      const li = document.createElement('li');
      li.textContent = `${p.name} (${p.id_number})`;
      ul.appendChild(li);
    });
    document.getElementById('loading').style.display = 'none';
  });
</script>

没错,这里用了 AJAX。为啥不用 Django 模板渲染?因为产品经理总想加“实时搜索”、“动态筛选”,与其后期重构,不如一开始就前后端分离。虽然这会让运维多配个 Nginx,但值得。

数据库设计:别让测试同事半夜打电话

医疗数据最怕什么?脏数据。曾经有个实习生把 birth_date 设成 CharField,结果线上录入“1990年”、“1990-01”、“1990/01/01”三种格式,ETL 脚本直接炸了。

Django 的 DateField 能强制格式,但还不够。我们加个 model clean:

from django.core.exceptions import ValidationError
from datetime import date

def clean(self):
    if self.birth_date > date.today():
        raise ValidationError("出生日期不能晚于今天")

另外,索引很重要!患者列表按姓名查询?给 namedb_index=True。身份证号查重?unique=True 自动建唯一索引。

字段 类型 是否索引 说明
id_number CharField(18) ✅ (唯一) 身份证号,业务主键
name CharField(100) 姓名,常用于模糊搜索
birth_date DateField 除非高频范围查询,否则不建

上线前记得用 python manage.py sqlmigrate patients 0001 看生成的 SQL,确认索引是否生效。

生产环境那些坑

本地跑得好好的,一上生产就 502?我太懂了。

  1. 静态文件:Django 默认不服务 static 文件。生产环境必须配 WhiteNoise 或 CDN。
  2. DEBUG=False:很多人忘了关 DEBUG,结果 SECRET_KEY 泄露,被扫出 SSRF。
  3. 数据库连接池:默认 SQLite 只能单线程。生产必须换 PostgreSQL,并调优 CONN_MAX_AGE

我们的部署流程是:GitHub Actions → Docker build → K8s。每次发版前,运维会盯着我说:“这次别再把 migrations 漏了啊!”——因为有一次我合并 PR 忘了跑 migrate,导致新字段查不到,凌晨三点被 PagerDuty 喊醒。

代码人生:从 CRUD 到架构思考

三年前我写 Django,只会 python manage.py startapp 然后狂写 views。现在,我会先画 ER 图、设计 API 响应结构、评估缓存策略。

Django 不只是个框架,它教会我用约束换安全。在医疗行业,一行错误的数据可能影响患者治疗。所以宁可牺牲一点灵活性,也要保证数据完整性。

最近看招聘,发现很多岗位要求 “Python + JS 全栈能力”。或许这就是趋势:后端不能只关心 ORM 和 serializer,也得懂前端怎么消费数据。所以我开始认真学 JavaScript 的异步处理、状态管理,甚至研究如何用 Web Workers 避免 UI 卡顿。

最后

这篇文章其实源于我准备面试时的复习笔记。如果你也正打算入坑 Django,记住:别怕文档厚,官方教程是最好的起点。遇到报错别慌,90% 的问题 Stack Overflow 上都有答案(剩下 10% 是你拼错了变量名)。

下周我可能会试试用 Django Channels 做实时通知——毕竟产品经理已经暗示“想要 WebSocket 支持”了。到时候再分享踩坑记录。

哦对了,如果你在医疗 IT 行业,欢迎交流!说不定哪天我们就在同一个会议室里,一起对着 Jira 里的 P0 Bug 抓狂呢 😅

代码人生,不止 CRUD。
—— 一个在 Mac 上敲代码、Windows 上擦屁股的 Python 开发

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝