Django переключатели, отображаемые в виде списка маркеров, внутри mark_safe () - PullRequest
0 голосов
/ 27 апреля 2020

Фон

Я использовал '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)

Это выводит как :

enter image description here

Проблема

Как вы можете видеть выше, точки с маркерами теперь также появляются рядом с «Да» и «Нет» несмотря на то, что я этого не хотел. Проверка элемента показывает, что это потому, что они также структурированы внутри неупорядоченного тега списка (несмотря на то, что мой тег ul заканчивался после 'cheese' в метке выше):

<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>

Есть ли способ, которым я мог бы остановить это и просто сохраняйте маркеры на «Пасте», «Рисе» и «Сыре», удаляя маркеры / список из «Да» и «Нет»?

1 Ответ

1 голос
/ 27 апреля 2020

Виджет RadioSelect использует элемент <ul> для отображения списка параметров. По умолчанию браузеры отображают <ul> элементы с маркером и обычно отступом 40px слева от каждого элемента.

Существует три способа исправить это. Вы можете добавить немного основы c CSS. Эти три метода даны в порядке рекомендации. Наилучшим вариантом на данный момент является использование CSS.

1. С CSS

Это лучший вариант. Выберите этот.

Первый: добавьте атрибут class к вашему RadioSelect виджету.

# forms.py

class FormFood(forms.Form):
    CHOICES = [ (1,'Yes'), (2, 'No')]
    response = forms.ChoiceField(
        widget=forms.RadioSelect(attrs={'class': "custom-radio-list"}),
        label=mark_safe("Do you like any of these foods? <ul><li>Pasta</li><li>Rice</li><li>Cheese</li></ul>"), choices=CHOICES)

Второй: Добавьте несколько CSS.

.custom-radio-list {
    list-style-type: none;
    padding: 0;
    margin: 0;
}

Для того чтобы этот ответ был более полным и округленным, предусмотрены следующие методы. Есть моменты, когда вам нужно изменить HTML или создать собственный виджет. Однако в вашей ситуации CSS - лучший вариант. Презентация должна в основном обрабатываться с CSS.

2. Создание собственного виджета

Создание собственного виджета довольно просто для простых виджетов.

Сначала: Создайте собственный виджет, который наследуется от класса RadioSelect, а затем используйте его в качестве виджета для вашего поля.

# forms.py

from django import forms


class MyRadioWidget(RadioSelect):
    template_name = 'myradiowidget.html'


class FormFood(forms.Form):
    CHOICES = [ (1,'Yes'), (2, 'No')]
    response = forms.ChoiceField(
        widget=MyRadioWidget,
        label=mark_safe("Do you like any of these foods? <ul><li>Pasta</li><li>Rice</li><li>Cheese</li></ul>"), choices=CHOICES)

Секунда: Добавьте шаблон HTML, в котором используются элементы <div>, а не <ul> и <li>.

<!-- /templates/myradiowidget.html -->

{% with id=widget.attrs.id %}<div{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>{% for group, options, index in widget.optgroups %}{% if group %}
  <div>{{ group }}<div{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for option in options %}
    <div>{% include option.template_name with widget=option %}</div>{% endfor %}{% if group %}
  </div></div>{% endif %}{% endfor %}
</div>{% endwith %}

3. Переопределить форму по умолчанию HTML

Вы можете переопределить виджет формы HTML шаблон.

Внимание! Это переопределит шаблон во всем проекте, включая администратора Django. !

Первый: Измените средство визуализации шаблона формы, чтобы использовать Django шаблонную основу.

# settings.py

FORM_RENDERER = "django.forms.renderers.TemplatesSetting"

Второй: Добавить ваш новый файл radio.html в каталоге template для переопределения виджета по умолчанию.

<!-- /templates/django/forms/widgets/radio.html -->

{% with id=widget.attrs.id %}<div{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>{% for group, options, index in widget.optgroups %}{% if group %}
  <div>{{ group }}<div{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for option in options %}
    <div>{% include option.template_name with widget=option %}</div>{% endfor %}{% if group %}
  </div></div>{% endif %}{% endfor %}
</div>{% endwith %}
...