用 Django 与 PostgreSQL 构建 CRUD 应用
Django + PostgreSQL 全攻略:安装配置数据库、定义模型、实现增删改查与搜索过滤,并讲解 Django 对 PostgreSQL 特有功能的支持。
直接回答:PostgreSQL 是 Django 官方推荐的生产级数据库:ORM 无缝集成,用 Python 类定义模型即可操作数据,还能直接使用数组、JSON、全文检索等 PostgreSQL 特有功能。本文以食谱应用为例走通完整 CRUD 流程。
为什么是 PostgreSQL
SQLite 适合开发和符合其并发限制的小型应用,MySQL 常见但 Django 生态的天平偏向 PostgreSQL:严格的数据完整性、强大的 JSON 支持、全文检索、数组/区间类型——Django 的 django.contrib.postgres 模块把这些特性变成了一等公民字段。
安装与配置
# 安装 PostgreSQL 后创建库与用户
sudo -u postgres psql
CREATE USER chef;
\password chef
CREATE DATABASE recipes_db OWNER chef;
pip install 'psycopg[binary]' # Django 的 PostgreSQL 驱动
# settings.py
import os
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "recipes_db",
"USER": "chef",
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": "localhost",
"PORT": "5432",
}
}
生产环境密码走环境变量,别写死在 settings 里。
定义模型
from django.db import models
class Recipe(models.Model):
title = models.CharField(max_length=200)
ingredients = models.JSONField(default=list) # PostgreSQL JSONB
steps = models.TextField()
prep_minutes = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add=True)
python manage.py makemigrations && python manage.py migrate 建表。
CRUD 实战
新增:
Recipe.objects.create(
title="番茄炒蛋",
ingredients=["番茄", "鸡蛋", "葱花"],
steps="打蛋→炒蛋→下番茄→出锅",
prep_minutes=15,
)
列表(视图):
def recipe_list(request):
recipes = Recipe.objects.order_by("-created_at")
return render(request, "recipes/list.html", {"recipes": recipes})
更新(写操作应在有登录、对象级权限和 CSRF 保护的 POST 视图内执行,使用 Form/Serializer 校验输入;以下为局部片段):
recipe = get_object_or_404(Recipe, pk=pk)
recipe.title = request.POST["title"]
recipe.save()
删除:
recipe = get_object_or_404(Recipe, pk=pk)
recipe.delete()
搜索过滤:
q = request.GET.get("q", "")
recipes = Recipe.objects.filter(title__icontains=q)
# PostgreSQL 全文检索(更强):
from django.contrib.postgres.search import SearchVector
recipes = Recipe.objects.annotate(search=SearchVector("title", "steps")).filter(search=q)
用好 PostgreSQL 特性
ArrayField:标签、配料列表的原生存储;JSONField(JSONB):半结构化数据可索引可查询;SearchVector:不装 Elasticsearch 也能有像样的全文检索;- 区间类型、约束排除等进阶特性按需探索。
常见问题(FAQ)
Q:Django 用 PostgreSQL 还是 MySQL?
A:新项目默认 PostgreSQL:功能更全、Django 支持更深、数据完整性更严。存量 MySQL 没必要为此迁移。
Q:JSONField 会不会不如独立表规范?
A:取决于数据是否需要按内部字段关联查询。配料列表这类"整体读写"的数据用 JSONB 很合适;需要按元素维度统计的,老老实实建关联表。
Q:连接数被打满怎么办?
A:先检查连接上限、worker 数及连接生命周期;持久连接可能增加占用。按部署模型使用池或 PgBouncer,Django 异步模式应禁用持久连接。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。