Django Allauth自定义消息:使用HTML / CSS样式化消息

7

默认情况下,Allauth的消息以文本文件的形式存储在模板目录中,它们看起来像这样:

{% load i18n %}
{% blocktrans %}You cannot remove your primary e-mail address ({{email}}).{% endblocktrans %}

这些使用了Django的模板标签,但不太适合HTML。我希望能对它们进行样式设置,得到类似于:

{% load i18n %}
<div class="alert alert-danger alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            {% blocktrans %}You cannot remove your primary e-mail address ({{email}}).{% endblocktrans %}
 </div>

但是上面的代码只是将HTML呈现为文本。我不能将这个HTML放在模板中,然后只需在模板中执行{{message}},因为我想按照每个消息的偏好来更改其中一些内容(至少是颜色!)。
我该如何实现这一点? 谢谢!
1个回答

15

模板是消息样式标记的位置,而不是消息 .txt 文件。您应该能够通过Django的默认值或必要时的条件语句来实现每种情况的变化。我看到您正在使用Bootstrap,对于许多用例,默认的Django messaging标记可以很好地映射到Bootstrap自己的警告类别。当您在视图中创建消息时...

messages.success(request, 'You have logged in successfully.')

...每个Django消息都包含其级别的字符串表示形式('info''success'等)作为tags属性。您可以使用这些标签属性来满足许多上下文格式化需求。因此,您可以将其传递到(例如基本)模板中,如下所示:

<div class="alert alert-{{ messages.tags }} alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
        <span aria-hidden="true">&times;</span>
    </button>
    {{ message }}
</div>
如果您的消息级别为success,则此处呈现的CSS类将是alert-success,因此Bootstrap将显示绿色警报。 如果状态是info,则为alert-info和蓝色等等。 Django的默认消息级别和字符串表示定义在django/contrib/messages/constants.py中:
DEFAULT_TAGS = {
    DEBUG: 'debug',
    INFO: 'info',
    SUCCESS: 'success',
    WARNING: 'warning',
    ERROR: 'error',
}

DEFAULT_LEVELS = {
    'DEBUG': DEBUG,
    'INFO': INFO,
    'SUCCESS': SUCCESS,
    'WARNING': WARNING,
    'ERROR': ERROR,
}

与 Bootstrap 的 默认警告类和上下文格式 相比较:

Bootstrap 默认警告类和上下文颜色

infosuccesswarning 类与 Django 的消息级别相同,因此这些消息将自动获得 Bootstrap 的正确格式。但是 Django 最严重的级别是 error,而 Bootstrap 的最严重级别是 danger

一个建议的解决方案是:保持 Django 模板标签不变,这将给元素添加一个名为 alert-error 的类。然后在 HTML 模板中的某个位置使用几行 Javascript 将 alert-danger 作为额外的类添加到这些元素中:

// Javascript somewhere in your HTML template
let errorElements = document.getElementsByClassName('alert-error');
[...errorElements].forEach(el => {el.classList.add('alert-danger')});
这将向具有“alert-error”类的元素添加“alert-danger”类。Bootstrap将忽略“alert-error”,但是添加“alert-danger”到元素的类列表中,它们将获得Bootstrap的红色上下文格式化。
如果您想专门使用allauth自定义事物,例如将所有auth默认设置的消息级别设置为“info”级别而不是“success”,则可以直接更改allauth.account.views(和allauth.socialaccount.views)中的这些内容。
您还可以传递额外的标签给Django消息,并将其用于条件格式化:请参见文档中的extra message tags此答案

1
你说:“或者作为'ERROR': MESSAGES_ERROR_STRING保持Django核心代码不变,并在您的设置文件中定义该常量。”但这需要更改Django核心代码,对吧?除此之外,非常感谢您详细的回答! - Max Smith
是的,虽然这意味着您仍然可以在每个项目的设置文件中定义默认值,以便在运行相同Django安装的任何其他项目时使用。此外,这样做可以使更改更加明确,易于维护,而不是将其埋藏起来。这是一种方式。 - birophilo
2
更新于2020年。这仍然有效,只需要使用{{ message.tags }}而不是{{ messages.tags }} - Simone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接