You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中RadioSelect如何渲染HTML格式的选项文本?

解决Django中RadioSelect选项HTML标签不渲染的问题

问题原因

直接使用{{ form.fielda | safe }}无效,是因为Django在渲染表单字段时,已经对每个选项的label单独做了转义处理,整体添加safe过滤器无法还原单个选项里的HTML标签。

解决方案

方案1:自定义RadioSelect Widget

通过重写Widget的create_option方法,将选项标记为安全文本,避免转义:

  1. 在forms.py中导入必要模块并定义自定义Widget:
from django.forms import RadioSelect
from django.utils.safestring import mark_safe

class HTMLRadioSelect(RadioSelect):
    def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
        option = super().create_option(name, value, label, selected, index, subindex, attrs)
        # 将label标记为无需转义的安全文本
        option['label'] = mark_safe(label)
        return option
  1. 在ModelForm中使用这个自定义Widget:
class forma(forms.ModelForm):
    class Meta:
        model = modela
        widgets = {'fielda': HTMLRadioSelect}
        fields = '__all__'

方案2:在Form中重写字段,手动处理choices

直接在Form字段中把带HTML的选项文本标记为安全:

from django.forms import TypedChoiceField, RadioSelect
from django.utils.safestring import mark_safe

class forma(forms.ModelForm):
    fielda = TypedChoiceField(
        choices=[
            (True, mark_safe('some <b>bold</b> text')),
            (False, 'zzz')
        ],
        widget=RadioSelect,
        coerce=lambda x: x == 'True',  # 确保值转换为布尔类型
        initial=True
    )

    class Meta:
        model = modela
        fields = '__all__'

方案3:模板中手动遍历选项并应用safe

直接在模板里逐个处理选项的label,使用safe过滤器:

修改a.html内容:

{% for choice in form.fielda %}
    <div>
        <input type="radio" 
               id="{{ choice.id_for_label }}" 
               name="{{ choice.name }}" 
               value="{{ choice.value }}" 
               {% if choice.is_selected %}checked{% endif %}>
        <label for="{{ choice.id_for_label }}">{{ choice.label|safe }}</label>
    </div>
{% endfor %}

内容的提问来源于stack exchange,提问作者dibery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:03:10