diff --git a/oauth2_provider/templates/oauth2_provider/application_client_secret_message.html b/oauth2_provider/templates/oauth2_provider/application_client_secret_message.html
new file mode 100644
index 000000000..eaada0f05
--- /dev/null
+++ b/oauth2_provider/templates/oauth2_provider/application_client_secret_message.html
@@ -0,0 +1,9 @@
+{% load i18n %}
+
+{% block message_content %}
+{% blocktranslate %}
+The application client secret is:
+
{{ client_secret }}
+This will only be shown once, so copy it now!
+{% endblocktranslate %}
+{% endblock %}
diff --git a/oauth2_provider/views/application.py b/oauth2_provider/views/application.py
index 3db88ebfd..202412003 100644
--- a/oauth2_provider/views/application.py
+++ b/oauth2_provider/views/application.py
@@ -1,9 +1,8 @@
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.forms.models import modelform_factory
+from django.template.loader import render_to_string
from django.urls import reverse_lazy
-from django.utils.safestring import mark_safe
-from django.utils.translation import gettext as _
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView
from ..models import get_application_model
@@ -53,14 +52,9 @@ def form_valid(self, form):
messages.add_message(
self.request,
messages.SUCCESS,
- # Since the client_secret is not user-supplied, we can manually mark this entire
- # string as safe so Django doesn't re-encode the HTML markup
- mark_safe(
- _(
- "The application client secret is:
%s
"
- "This will only be shown once, so copy it now!"
- )
- % form.instance.client_secret
+ render_to_string(
+ "oauth2_provider/application_client_secret_message.html",
+ {"client_secret": form.instance.client_secret},
),
)
return super().form_valid(form)