Django 5.2 LTS 与 6.x 的区别对比

这篇讲什么

  • 这篇记录本套笔记的版本基线为什么从 6.1.x 改回 5.2 LTS,以及 5.2.19 与 6.1.3 之间到底差在哪。
  • 结论都有实测支撑:56 条 API 探针跑出的差异清单、pip 装 django-celery-beat 时静默降级 Django 的日志、以及本笔记已经改过的现代写法在 5.2.19 上重新跑通的结果。真要升 6.x(或从 6.x 回退),文末的检查清单可以照着过一遍。

先说结论

  • 这一轮把本套笔记的版本基线从 6.1.x 改回 5.2 LTS(实测环境是 5.2.19),等 2027 年 4 月 6.2 LTS 正式发布后整体切到 6.2 LTS。
  • 回退不是「6.x 不好」,而是两条实测结果叠加之后的选择:
    1. 生态包的上限还没放开。django-celery-beat 2.9.0 的元数据写着 Django<6.1,>=2.2,在 6.1.3 环境里 pip install django-celery-beat 会静默把 Django 降到 6.0.10(日志见下文),等于你以为在用 6.1,其实用的是 6.0。
    2. 6.x 的破坏性变更集中且没必要现在吃。56 条探针跑下来,6.x 相对 5.2 移除了 11 项、改了 20 项行为、新增了 14 项;而这套笔记需要的新特性(CSP 中间件、django.tasks、AsyncPaginator)一个都用不上。
  • 反向验证也做了:本套笔记第一批改的现代写法(re_path、app_name 命名空间、外键 on_delete、Signal()、请求头判 Ajax)在 5.2.19 上真跑通了 —— makemigrations、migrate、check 全部 rc=0,四个页面 HTTP 200。所以换基线不影响已经改完的内容。

支持时间表:LTS 到底意味着什么

  • 下面是 2026-11-04 从官方下载页抓的支持表(列名照抄:Release Series / Latest Release / End of mainstream support / End of extended support):

    发行系列 最新补丁版 主流支持结束 延长支持结束 今天(2026-11-04)的状态
    5.2 LTS 5.2.19 2025-12-03 2028-04 只剩安全修复和数据丢失修复
    6.0 6.0.10 2026-08-04 2027-04 只剩安全修复和数据丢失修复
    6.1 6.1.3 2027-04 2027-12 还在主流支持期内
  • 「主流 / 延长」两级支持的具体含义(官方发布流程文档的措辞):

    • 主流支持期:会往这条发布分支上回合的补丁包括 —— 安全问题、数据丢失 bug、崩溃 bug、新特性里的重大功能 bug,以及本系列引入的回归。
    • 延长支持期:只收安全修复和数据丢失修复,其它 bug 不再动这条分支。
    • 所以 5.2 现在的状态是「安全无忧、bug 自理」,到 2028-04 才失去支持;对一个学习笔记加个人项目来说,这个窗口足够长。
  • Python 侧的支持矩阵(官方 FAQ 表 + 本机 Requires-Python 元数据实测):

    Django 官方支持的 Python 元数据 Requires-Python(本机实测)
    5.2 3.10、3.11、3.12、3.13、3.14(3.14 从 5.2.8 起) >=3.10
    6.0 3.12、3.13、3.14 —
    6.1 3.12、3.13、3.14、3.15(3.15 从 6.1.3 起) >=3.12
    • 本机 django 环境和 base 都是 Python 3.14.10,5.2.19 与 6.1.3 都在官方支持范围内,所以「选 5.2 还是选 6.1」不能用 Python 版本当理由。
    • 真正的差别在 3.10、3.11:只有 5.2 还认它们。公司里那台不能升级 Python 的老机器要装 Django,5.2 是唯一选项。

6.2 之后的游戏规则变了

  • 官方 Future Roadmap(同一页面,2026-11-04 抓的):

    发行系列 发布 主流支持结束 延长支持结束
    6.2 LTS 2027-04 2027-12 2030-04
    2028 2028-01 2029-01 2031-01
    2029 2029-01 2030-01 2032-01
  • 官方原话里的两个要点,直接决定了「以后要不要再找 LTS」:

    • 6.2 是最后一版按 A.B 命名、也是最后一次「指定 LTS」:原文是 「Django 6.2 is the final release under the previous versioning and support policy」。
    • 从 Django 2028 起每一版都有三年支持,LTS 这个词不再有特殊含义:原文是 「Starting with Django 2028, every feature release receives the same three-year support period」,节奏也从「大约每 8 个月一版」改成「每年一版,1 月发」。
  • 顺手抓到的一个佐证:6.1.3 的 django/conf/__init__.py 里已经在用 RemovedInDjango2028Warning 这个新的弃用级别,弃用提示直接写着「Django 2028 会移除」。

  • 对本套笔记的意义:2027-04 切到 6.2 LTS 之后,下一次迁移是 2028-01 的 Django 2028,而且从此以后每年一版、每版支持三年,选版本的逻辑会比现在简单得多。

56 条探针逐项对比

  • 做法是把同一份代码分别在两个解释器上执行再逐项 diff:56 项里 11 项是 6.x 移除、14 项是 6.x 新增、20 项行为不同、11 项相同。
  • 写探针时踩到的三个坑,值得单独记一下,否则会得到「两版相同」的假结论:
    1. 必须先 settings.configure()。不配 settings 时 forms.URLField()、serializers.serialize() 全是 ImproperlyConfigured,两版一样,就被判成「相同」了。

    2. getattr 要拿类而不是模块。getattr(django.db.backends.base.operations, "field_cast_sql") 一定 AttributeError,跟版本无关;上一版探针有 10 条栽在这里。

    3. django.contrib.postgres 的聚合函数会连带 import psycopg,本机没装驱动。想看它的签名就用 ast 解析源码文件,不要执行导入:

      1
      2
      3
      4
      5
      # 不导入模块,直接读源码里类定义的基类
      tree = ast.parse(open(path, encoding="utf-8").read())
      for node in tree.body:
      if isinstance(node, ast.ClassDef) and node.name == "ArrayAgg":
      print([ast.unparse(b) for b in node.bases])

6.x 移除的(5.2 上还在)

探针 5.2.19 实测 6.1.3 实测 说明
django.utils.itercompat.is_iterable <function is_iterable> ModuleNotFoundError: No module named 'django.utils.itercompat' 只会撞在老三方库里
django.db.models.enums.ChoicesMeta <class '...ChoicesType'>(是别名) AttributeError: module 'django.db.models.enums' has no attribute 'ChoicesMeta' 同上
BaseDatabaseOperations.field_cast_sql 存在于 operations.py:217 AttributeError: type object 'BaseDatabaseOperations' has no attribute 'field_cast_sql' 自定义 DB backend 才会碰
Prefetch.get_current_queryset <function Prefetch.get_current_queryset>(5.2 已弃用) AttributeError 改名 get_current_querysets(level)
ForwardManyToOneDescriptor.get_prefetch_queryset <function ...> AttributeError 改名 get_prefetch_querysets(instances, querysets=None)
ModelAdmin.log_deletion <function ModelAdmin.log_deletion> AttributeError 只剩 log_deletions(request, queryset),批量语义
FileSystemStorage.OS_OPEN_FLAGS 34049 AttributeError 类属性删了,自定义存储别再去读它
ForeignObject.get_joining_columns <function ForeignObject.get_joining_columns> AttributeError 用 get_joining_fields() 一族
CheckConstraint(check=...) 能构造,但报 RemovedInDjango60Warning: CheckConstraint.check is deprecated in favor of .condition. TypeError: CheckConstraint.__init__() got an unexpected keyword argument 'check' 一律写 condition=
format_html("x")(零参数) 'x' TypeError: args or kwargs must be provided. 只拼静态字符串时改用普通字符串常量

默认值与签名变了

探针 5.2.19 6.1.3 影响
global_settings.DEFAULT_AUTO_FIELD django.db.models.AutoField django.db.models.BigAutoField 新项目的自增主键位数不同,会产生一次真实迁移
PBKDF2PasswordHasher.iterations 1000000 1500000 6.x 上登录时自动升级哈希参数,用户无感
URLField().assume_scheme http https 表单把 example.com 补成哪个协议
URLField().to_python("example.com") http://example.com https://example.com 存库结果直接不同
global FORMS_URLFIELD_ASSUME_HTTPS 有这个设置 已删 5.2 上它控制上面那个警告
Model.save 签名 (self, *args, force_insert=False, ...) (self, *, force_insert=False, ...) 6.x 不允许位置参数,obj.save(True) 会炸
serializers.serialize("json", []) '[]' '[]\n' 6.x 结尾多一个换行,做摘要/字节比对要留意
staticfiles.finders.find 签名 (path, find_all=False, **kwargs) (path, find_all=False) 自定义 finder 的转发写法要跟着改
ArrayAgg 的基类 ['OrderableAggMixin', 'Aggregate'] ['Aggregate'] ordering= 这个关键字没人接了(见「静默变化」一节)
Aggregate.__init__ 参数 无 order_by 多了 order_by 6.x 用 order_by=,且不是所有聚合都允许
global USE_BLANK_CHOICE_DASH 无此设置 False(且已被标 RemovedInDjango2028Warning) 以后改 django.db.models.fields.BLANK_CHOICE_LABEL
global SIGNED_COOKIE_LEGACY_SALT_FALLBACK True(core/signing.py 真的在读) False,设置本身已弃用 6.x 不再兜底旧 cookie 盐
包元数据 Requires-Python >=3.10 >=3.12 老 Python 只能选 5.2

6.x 新增的(5.2 上确实没有)

探针 6.1.3 实测 5.2.19 要不要为了它升 6.x
django.utils.csp.CSP <enum 'CSP'> ModuleNotFoundError 想要 CSP 也可以先用 django-csp 三方包
django.middleware.csp.ContentSecurityPolicyMiddleware 存在 ModuleNotFoundError: No module named 'django.middleware.csp' 同上,注意模块路径不是 django.middleware.security
django.tasks.task + global TASKS TASKS = {'default': {'BACKEND': 'django.tasks.backends.immediate.ImmediateBackend'}} 无 django.tasks 官方版的「延迟任务」,本套笔记用 Celery,不需要
AsyncPaginator 存在 AttributeError ASGI 场景才有意义
models.StringAgg / AnyValue / BitAnd 进核心 django.db.models 只能从 django.contrib.postgres 拿 PostgreSQL 专属聚合进了核心,非 PG 库也能 import
models.JSONNull django.db.models.expressions.JSONNull AttributeError JSON 字段比较用
exceptions.ObjectNotUpdated + 模型子类 NotUpdated <class 'probe.ProbeNotUpdated.NotUpdated'>,基类 ObjectNotUpdated 模型类上「无 NotUpdated」 save(update_fields=...) 没影响行时能显式报错
models.FETCH_ONE / FETCH_PEERS / FETCH_RAISE、QuerySet.fetch_mode() 三个都是 fetch_modes 里的单例,QuerySet.fetch_mode(self, fetch_mode) 文档串是 「Set the fetch mode for the QuerySet.」 全部 AttributeError 6.1 的预取内存控制
models.DB_CASCADE <DatabaseOnDelete>,可当 on_delete 用 AttributeError 把级联交给数据库外键,需要 DB 支持
core.mail.mailers(MailersHandler) <django.core.mail.handler.MailersHandler object>;django.core.mail.handler 模块本身 5.2 没有 无 MAILERS 是新的邮件配置入口,get_connection() 已标弃用但仍可用
forms.Stylesheet django.forms.widgets.Stylesheet AttributeError 表单媒体 CSS 声明
模板标签 partialdef 已注册 未注册 {% partialdef %} / {% partial %} 模板片段复用
模板标签 querystring 已注册 已注册 这条是「相同」,5.2 就有

包兼容性矩阵:回退的直接原因

  • 在 django 环境(Python 3.14.10)把 Django==5.2.19 和 21 个生态包全装一遍,逐个 import 复测,pip check 输出 No broken requirements found.:

    包 版本 5.2.19 环境实测
    Django 5.2.19 import OK
    djangorestframework 3.18.3 import OK
    django-filter 26.2 import OK
    drf-spectacular 0.30.0 import OK
    celery 5.6.3 import OK
    django-celery-results 2.6.0 import OK
    django-celery-beat 2.9.0 import OK(6.1 上就是它把 Django 拖下去的)
    redis 8.1.0 import OK
    django-redis 7.0.0 import OK
    PyMySQL 1.2.3 import OK
    cryptography 50.0.2 import OK
    Pillow 13.0.0 import OK
    gunicorn 26.2.0 import OK
    uvicorn 0.54.0 import OK
    whitenoise 6.12.0 import OK
    django-debug-toolbar 8.0.0 import OK
    django-tinymce 5.0.0 import OK
    django-simple-captcha 0.7.0 import OK
    django-ratelimit 4.1.0 import OK,模块名是 django_ratelimit
    django-cors-headers 4.9.0 import OK
    django-unfold 0.110.1 import OK,它自己要求 django>=5.2
    sentry-sdk 2.73.0 import OK
  • 同批包在 6.1.3 上唯一的硬伤就是 django-celery-beat。它的元数据实测内容:

    1
    2
    python -m pip install --no-deps --target /tmp/x django-celery-beat
    python -c "from importlib.metadata import distribution as d; print(d('django-celery-beat').metadata['Requires-Dist'])" 2>&1
    1
    2
    3
    celery<6.0,>=5.2.3 ; importlib-metadata<5.0; python_version < "3.8" ;
    django-timezone-field>=5.0 ; backports.zoneinfo; python_version < "3.9" ;
    tzdata ; python-crontab>=2.3.4 ; cron-descriptor<2.0.0,>=1.2.32 ; Django<6.1,>=2.2
    • 这条 Django<6.1,>=2.2 就是全部故事:pip 为了满足它,宁愿把 Django 换小。

    • 当时 6.1.3 环境里的真实安装日志(switch_to_django52.py 之前那次):

      1
      2
      Successfully installed Django-6.0.10 cron-descriptor-1.4.5
      django-celery-beat-2.9.0 django-timezone-field-7.2.2 python-crontab-3.4.0

      注意 Django-6.0.10,这就是「静默降级」:命令 rc=0,没有任何 warning 行提示你 Django 被换了。

  • 另外三个装不上的包,换成 5.2 也照样装不上(本次在 5.2.19 环境里用 --no-deps --target 复测,报错逐字一致):

    包 实测错误 根因跟 Django 版本有关吗
    uwsgi AttributeError: module 'os' has no attribute 'uname' 然后 Failed to build 'uwsgi' ... 无关,Windows 上没有 os.uname,跟 Python 3.14 也无关
    xadmin UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 3444 然后 Failed to build 'xadmin' when getting requirements to build wheel 装这一步无关(是本机默认 GBK 读它自己的 setup.py);但用 PYTHONUTF8=1 绕过后 import xadmin 会炸 NameError: name 'reload' is not defined,那是 Python 2 代码,跟 Django 版本也没关系
    djcelery ERROR: Could not find a version that satisfies the requirement djcelery (from versions: none) 有关,PyPI 上已经没有这个包了,Celery 4+ 用 django-celery-beat / django-celery-results
  • 原来这张表里还有第四个 django-simpleui(当时报 FileNotFoundError: ... 'README.md'),2026-11-05 复测已经不成立了:上游改用日历版本号,2026.1.13 能装能用,连旧的 4.0.3 现在也能重新构建成功,所以它挪到了《Django-常用插件》的「可用」清单里。这条也算给「装不上」这类结论提个醒:它会随上游重新发包而失效,要定期复测。

老写法在 5.2 和 6.1 上死得一模一样

  • 这批 API 早在 2.0 到 4.0 就被删光了,所以「换回 5.2」不会让第一批的改写作废。django_api_probe.py 现在会把 18 条老写法在两个解释器上各跑一次并逐字比对:18 条全部一致(比对前把报错里各自的安装路径归一化成 (site-packages),否则「不一致」全是路径差异造成的假阳性)。

    旧写法 5.2.19 与 6.1.3 共同的实测结果 现代写法
    from django.conf.urls import url ImportError: cannot import name 'url' from 'django.conf.urls' (site-packages). Did you mean: 'urls'? from django.urls import path, re_path
    from django.core.urlresolvers import reverse ModuleNotFoundError: No module named 'django.core.urlresolvers' from django.urls import reverse
    from django.utils.translation import ugettext ImportError: cannot import name 'ugettext' from 'django.utils.translation' (site-packages) gettext / gettext_lazy
    from django.utils.encoding import force_text ImportError: cannot import name 'force_text' from 'django.utils.encoding' (site-packages) force_str / smart_str
    from django.utils import six ImportError: cannot import name 'six' from 'django.utils' (site-packages) 删掉,直接 Py3 写法
    Signal(providing_args=[...]) TypeError: Signal.__init__() got an unexpected keyword argument 'providing_args' Signal()
    ForeignKey("Grade") TypeError: ForeignKey.__init__() missing 1 required positional argument: 'on_delete' ForeignKey("Grade", on_delete=models.CASCADE)
    request.is_ajax() 有 is_ajax 吗: False request.headers.get("x-requested-with") == "XMLHttpRequest"
    AUTH_PROFILE_MODULE 设了之后 get_user_model() 仍是 <class 'django.contrib.auth.models.User'> 删掉,用 OneToOneField
    render_to_string 签名 (template_name, context=None, request=None, using=None) 显式写 request=request
  • 现代最小工程在 5.2.19 上的实跑输出(2026-11-04 抓的):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    4) makemigrations rc=0 Migrations for 'blog':
    blog\migrations\0001_initial.py
    + Create model Grade
    + Create model Student
    5) migrate rc=0 Applying sessions.0001_initial... OK
    6) check rc=0 System check identified no issues (0 silenced).
    7) 命名空间反向解析 rc=0 reverse: /students/5/ 模板里 url: /fired/ static 标签: /static/x.css
    8) GET / rc=200 body={"ajax": true, "students": 0}
    9) GET /students/7/ rc=200 body=pk=7
    10) GET /fired/ rc=200 body=signal sent
    11) GET /admin/login/ rc=200 字节 4160

最需要提防的是「静默变化」

  • 上面这些 ImportError 都算友好 —— 立刻炸、信息明确。真正危险的是不报错但行为变了这一类,实测到三个:

  • 1)聚合函数的 ordering= 掉了。5.2 里 ArrayAgg、 JSONBAgg、 StringAgg 都继承 OrderableAggMixin,这个 mixin 的 __init__ 参数是 ['order_by', 'ordering', 'self'];6.1 里三个类都不再继承它(who_uses 探针返回「无人继承」),OrderableAggMixin.__init__ 也「方法未找到」。于是:

    1
    2
    3
    4
    5
    6
    from django.db.models import StringAgg

    a = StringAgg("name", ",", ordering=["-id"]) # 5.2 靠 mixin 接住;6.1 没人接
    b = StringAgg("name", ",", order_by=["-id"]) # 6.x 的正确写法
    print(a.extra)
    print(b)
    1
    2
    3
    # 6.1.3 实测输出(5.2.19 上 core 里还没有 StringAgg,用 Count 演示同一机制)
    {'ordering': ['-id']}
    StringAgg(F(name), StringAggDelimiter(F(,)), order_by=OrderBy(F(id), descending=True))
    • 关键点:未知关键字会被 Aggregate.__init__(**extra) 咽进 .extra 里,不报错、check 也不管,SQL 里的排序就这么没了。5.2 与 6.1 上 Count("id", ordering=["-pk"]) 都是 .extra == {'ordering': ['-pk']},两版一样沉默。
    • 6.1 里 Aggregate.__init__ 的参数多了 order_by,但不是所有聚合都允许:Count("id", order_by=["-pk"]) 直接 TypeError: Count does not allow order_by.。
  • 2)JSON 序列化多了个结尾换行:5.2 是 '[]',6.1 是 '[]\n'。拿序列化结果算哈希、比对 fixture、或者做接口幂等校验的代码会莫名其妙对不上。

  • 3)cookie 签名盐的兜底默认值反了:SIGNED_COOKIE_LEGACY_SALT_FALLBACK 在 5.2.19 是 True 且 core/signing.py:_unsign_cookie 真的在读它(旧盐验签失败时兜一次),6.1 默认 False。6.1 里显式设置它还会吃两条 RemovedInDjango2028Warning,实测警告文案:

    1
    2
    3
    The SIGNED_COOKIE_LEGACY_SALT_FALLBACK transitional setting is deprecated. Remove it
    from your settings once legacy signed cookies have expired. They will not be accepted
    in Django 2028.
  • 顺手纠正一条我自己之前写错的结论。我原先说「startproject 生成的 settings.py 里 6.x 用双引号、5.x 用单引号」,这是错的:

    1
    2
    # 同一个 Django 5.2.19,只改 PATH 里有没有 black
    python -m django startproject nf E:\Desktop\Test\nf
    1
    2
    PATH 含 D:\ProgramData\anaconda3\Scripts(black.EXE 在这)时:INSTALLED_APPS 里是 "django.contrib.admin"
    PATH 屏蔽掉 black 之后:INSTALLED_APPS 里是 'django.contrib.admin'
    • 真实机制是 startproject 渲染完模板后调了一次 run_formatters(...),它会 shutil.which("black"),找到就跑 black --fast。5.2 和 6.1 这段代码都在 django/core/management/utils.py:166,一模一样。
    • 而 settings.py-tpl 模板本身两版都是单引号。所以引号风格取决于本机有没有装 black,跟版本无关;我用单引号去 str.replace 生成出来的 settings.py 才会静默失配(症状是 INSTALLED_APPS 没加进去,makemigrations 报 Model class blog.models.Grade doesn't declare an explicit app_label)。写脚本改生成文件时,正确做法是改完再 assert 期望内容确实出现在文件里。

真要升 6.x(或从 6.x 回退到 5.2)时的检查清单

  • 升级方向(5.2 → 6.x)按这个顺序走:
    1. 先钉住依赖:python -m pip freeze > base.txt,再看每个包的 Django 上限:
      1
      2
      3
      4
      5
      6
      7
      python - <<'PY'
      from importlib.metadata import distributions
      for d in sorted(distributions(), key=lambda x: x.metadata["Name"].lower()):
      for r in d.requires or []:
      if r.lower().startswith("django"):
      print(f"{d.metadata['Name']:28} {r}")
      PY
      把输出贴到笔记里,升级前先确认没有一个包写着 Django<6。
    2. 只在 5.2 上把弃用警告清零:python -W error::DeprecationWarning manage.py check,再跑一遍测试。5.2 上还有 RemovedInDjango60Warning,它清干净了才谈升级。
    3. 逐项替换(就是本笔记实测到的移除清单):CheckConstraint(check=) 改 condition=;Prefetch.get_current_queryset 改 get_current_querysets;get_prefetch_queryset 改 get_prefetch_querysets;ModelAdmin.log_deletion 改 log_deletions;自定义存储别再读 FileSystemStorage.OS_OPEN_FLAGS;format_html("纯文本") 改成普通字符串。
    4. 签名类:全仓搜 \.save( 后面跟位置参数的调用(obj.save(True) 这种),6.x 只接受关键字参数。
    5. 数据类:新项目在 6.x 下 DEFAULT_AUTO_FIELD 默认变成 BigAutoField;已有项目显式写着 AutoField 就别动,改了要生成一次真实迁移并评估回滚。
    6. 表单类:URLField 默认协议从 http 变 https,同时 FORMS_URLFIELD_ASSUME_HTTPS 这个设置消失。用户表里存的是「用户填的原样」还是「补全后的 URL」,要先确认。
    7. 聚合类:把 ordering= 全改成 order_by=,并且确认该聚合允许排序(Count 就不允许)。
    8. 最后跑真实请求,不是只跑 check。
  • 回退方向(6.x → 5.2)要动的是另一批:
    • 用掉过 django.tasks / TASKS 的地方改回 Celery;
    • ContentSecurityPolicyMiddleware(django.middleware.csp)改回 django-csp 或自己往 HttpResponse 塞头;
    • {% partialdef %} / {% partial %} 改回 {% include %} 加 with;
    • MAILERS 改回 EMAIL_BACKEND + get_connection();
    • 依赖 Model.NotUpdated / ObjectNotUpdated / DB_CASCADE / FETCH_ONE / forms.Stylesheet / AsyncPaginator 的代码全部撤掉,5.2 上它们不存在。

本套笔记现在的版本口径

  • 基线:Django 5.2.19 LTS,Python 3.14.10,conda 环境 django,安装走中科大镜像。
  • 全部 38 篇 Django 笔记里的写法统一按「5.2 与 6.x 都能跑」的标准来写,也就是:
    • 只用两版都存在且行为一致的现代 API(path / re_path / app_name / on_delete / Signal() / request.headers);
    • 6.x 才有的东西一律先讲 5.2 的做法,再用一行注明「6.0 起有 django.tasks 这类官方替代」,不拿它当默认写法;
    • 5.2 才有的(比如 SIGNED_COOKIE_LEGACY_SALT_FALLBACK = True)不写进示例。
  • 切换计划:2027-04 6.2 LTS 发布后整体切到 6.2 LTS,切之前先确认 django-celery-beat 放开上限、并且上面「升级方向」那 8 步在本仓跑通。

参考

本文结束 感谢您的阅读
正在加载今日诗词....