Python Django单选按钮显示为项目符号列表,位于mark_safe()内 背景

Python Django单选按钮显示为项目符号列表,位于mark_safe()内 背景,python,html,django,python-3.x,django-forms,Python,Html,Django,Python 3.x,Django Forms,我在表单中使用了“mark_safe()”,以便传递HTML指令并在表单标签中显示项目符号: class FormFood(forms.Form): CHOICES = [ (1,'Yes'), (2, 'No')] response = forms.ChoiceField(widget=forms.RadioSelect, label=mark_safe("Do you like any of these foods? <ul><l

我在表单中使用了“mark_safe()”,以便传递HTML指令并在表单标签中显示项目符号:

class FormFood(forms.Form):
    CHOICES = [ (1,'Yes'), (2, 'No')]
    response = forms.ChoiceField(widget=forms.RadioSelect,
              label=mark_safe("Do you like any of these foods? <ul><li>Pasta</li><li>Rice</li><li>Cheese</li></ul>"), choices=CHOICES)
class FormFood(forms.Form):
选项=[(1,'Yes'),(2,'No')]
response=forms.ChoiceField(widget=forms.RadioSelect,
label=mark\u safe(“你喜欢这些食物吗?
  • 面食
  • 米饭
  • 奶酪
    • ”),choices=choices)
这一结果如下:

问题 正如你在上面所看到的,尽管我不想这样,但要点现在也出现在“是”和“否”旁边。检查元素后发现,这是因为它们也是在无序列表标签中构造的(尽管我的ul标签在上面的标签中以“cheese”结尾):


你喜欢这些食物吗?
  • 面食
  • 米饭
  • 奶酪

有没有一种方法可以阻止这种情况,只保留“意大利面”、“米饭”和“奶酪”上的项目符号,同时从“是”和“否”中删除项目符号/列表?

RadioSelect小部件使用
元素列出选项。默认情况下,浏览器显示带有项目符号的
元素,每个元素的左侧通常有40px的填充

有三种方法可以解决这个问题。您可以添加一些基本的CSS。这三种方法按推荐顺序给出。到目前为止,最好的选择是使用CSS

1.使用CSS 这是最好的选择。选择这个

首先:
class
属性添加到
RadioSelect
小部件中

#forms.py
食品类(forms.Form):
选项=[(1,'Yes'),(2,'No')]
响应=forms.ChoiceField(
widget=forms.RadioSelect(attrs={'class':“自定义无线电列表”}),
label=mark\u safe(“你喜欢这些食物吗?
  • 面食
  • 米饭
  • 奶酪
    • ”),choices=choices)
Second:添加一些CSS

。自定义收音机列表{
列表样式类型:无;
填充:0;
保证金:0;
}
提供以下方法使此答案更加完整和全面。有时您需要修改HTML或创建自定义小部件。然而,在您的情况下,CSS是最好的选择。演示应该主要用CSS来处理

2.创建自定义小部件 对于简单的小部件,创建自定义小部件非常简单

首先:创建一个从
RadioSelect
类继承的自定义小部件,然后将其用作字段的小部件

#forms.py
来自django导入表单
类MyRadioWidget(RadioSelect):
模板名称='myradiowidget.html'
食品类(forms.Form):
选项=[(1,'Yes'),(2,'No')]
响应=forms.ChoiceField(
widget=MyRadioWidget,
label=mark\u safe(“你喜欢这些食物吗?
  • 面食
  • 米饭
  • 奶酪
    • ”),choices=choices)
第二:添加一个HTML模板,该模板使用
元素而不是
  • 元素

    
    {%with id=widget.attrs.id%}{%widget.optgroups%}{%if group%}
    {{group}{%endif%}{%for options%}中的选项
    {%include option.template_name with widget=option%}{%endfor%}{%if group%}
    {%endif%}{%endfor%}
    {%endwith%}
    
    3.覆盖默认表单HTML 您可以覆盖表单小部件HTML模板

    注意:这将覆盖整个项目的模板,包括Django管理员

    首先:更改表单模板呈现程序以使用Django模板后端

    #settings.py
    FORM_RENDERER=“django.forms.renderers.templateSetting”
    
    Second:将新的
    radio.html
    文件添加到
    模板
    目录以覆盖默认小部件

    
    {%with id=widget.attrs.id%}{%widget.optgroups%}{%if group%}
    {{group}{%endif%}{%for options%}中的选项
    {%include option.template_name with widget=option%}{%endfor%}{%if group%}
    {%endif%}{%endfor%}
    {%endwith%}
    
    可能会有帮助。我明白了,用CSS添加一个类和目标。这应该行得通。我想知道是否有更优雅的东西,我可以从后端做,但前端修复工程一样好。谢谢你,你的ul标签结束得不对吗<代码>嗨,莫吉特,发现得好!我只是把它弄好了。在这里传输而不是在我的代码中传输时是一个输入错误,不幸的是选项4:在模板中的无线电字段上循环,正如在“无需添加自定义类”中所解释的,您只需在CSS中选择
      元素id:
      \id\u response
      @djvg选项4是最简单的解决方案。工作完美。
      <form method="POST">
          <label for="id_response_0">Do you like any of these foods?
              <ul>
                  <li>Pasta</li>
                  <li>Rice</li>
                  <li>Cheese</li>
              </ul>
          </label>
          <ul id="id_response">
              <li>
                  <label for="id_response_0">
                      <input type="radio" name="response" value="1" required="" id="id_response_0"> Yes
                  </label>
      
              </li>
              <li>
                  <label for="id_response_1">
                      <input type="radio" name="response" value="2" required="" id="id_response_1"> No
                  </label>
      
              </li>
          </ul>
          <input type="hidden" name="csrfmiddlewaretoken" value="FaOTY4WlVLFMl3gNtut8BJihJKub1Is0wRJRxxLck1e2eJocJVXRiGoOLDr9jdvx">
          <input type="submit">
      </form>