用 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 异步模式应禁用持久连接。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台