格式化&符号会添加意外字符

Formatting ampersand adds unexpected characters

使用 Djoser 我正在尝试为我的前端生成正确的 url。我的 url 字符串中必须有 & 符号,Djoser 在将它发送到我的前端之前对其进行格式化。 url 看起来像:

https://localhost:4200/activate?id=MjA&token=540-cad5f834d5508ebdd78e

但我得到的最终结果看起来像 note "amp;" 在 &:

之后
http://localhost:4200/activate?id=MjE&token=541-c0437e0afd6261fd4833

我尝试了以下解决方案,但其中 none 有效 (\u0026, {\u0026}, {\u0026:c}, &&):

print("https://localhost:4200/activate?id={uid}\u0026token={token}".format(uid="MjA", token="540-cad5f834d5508ebdd78e"))
print("https://localhost:4200/activate?id={uid}{\u0026}token={token}".format(uid="MjA", token="540-cad5f834d5508ebdd78e")) <-- returns KeyError: '&'
print("https://localhost:4200/activate?id={uid}{\u0026:c}token={token}".format(uid="MjA", token="540-cad5f834d5508ebdd78e")) <-- returns KeyError: '&'

注意: 我不能直接更改 format() 部分的代码,这将由 Djoser 处理。我可以通过的部分实际上只是将字符串值分配给激活 url 就像那里:'ACTIVATION_URL': 'activate?id={uid}{\u0026:c}token={token}', 所以我必须在这个字符串中写我的解决方案。

注意 2: 我在 jupiter 上试过了,一切正常,我这样做是对的 url:

print("https://localhost:4200/activate?id={uid}\u0026token={token}".format(uid="MjA", token="540-cad5f834d5508ebdd78e"))

直接将& returns添加到&

后面的url和amp;

更新 Djoser 模板覆盖

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        ...
    },
]

经过反复讨论,原来 Djoser 想要发送一封激活邮件,内容是从 a Django template 生成的。问题是 Django 默认会 HTML 转义,所以 & 字符被转换为 HTML 实体,&amp;,这不是这里想要的。

答案是通过过滤器将 url 标记为 HTML 安全。这实际上意味着用 {{ url|safe }} 替换 {{ url }}。最好的方法是创建一个新模板来覆盖 Djoser 提供的模板并放入所需的内容。此模板需要作为 "email/activation.html" 驻留在项目模板区域中。 Django 中也有一些关于 how this is done 的文档。

一旦模板正常工作,那么 url 应该直接发出而不进行转义。