简体   繁体   中英

Formatting ampersand adds unexpected characters

Using Djoser Im trying to generate right url for my frontend. I have to have ampersand in my url string and Djoser do format this url before sending it to my frontend. The url looks like:

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

But the final result that I get looks like note "amp;" after & :

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

I tried following solutions but none of them works (\&, {\&}, {\&: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: '&'

NOTE: I can't directly change code in format() part, this will be handled by Djoser. The part that I can pass is actually only assign the string value to activation url like there: 'ACTIVATION_URL': 'activate?id={uid}{\&:c}token={token}', So I have to write my solution in this string.

NOTE2: I tried it in jupiter, there all works fine, I get the right url when I do it this way:

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

在此输入图像描述

Directly adding & returns to frontend same url with amp; behind &

UPDATE Djoser template overwriting

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

在此输入图像描述

After some back and forth discussion, it turns out that Djoser wants to send an activation email and the contents are being generated from a Django template . The issue is that Django does HTML escaping by default, so the & character is being converted to an HTML entity, &amp; , which is not what is desired here.

The answer is to mark the url as being HTML safe by piping it through a filter. This effectively means replacing {{ url }} with {{ url|safe }} . The best way to do this is to create a new template to override the one provided by Djoser and put in the required content. This template needs to reside in the project templates area as "email/activation.html". There is some documentation in Django on how this is done too.

Once the template is working correctly, then the url should be emitted directly with no escaping.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM