Стиль пули Django ModelMultipleChoiceField

#django #django-forms

#django #django-формы

Вопрос:

У меня есть форма, которая предлагает варианты для подписки на списки рассылки.

 field = forms.ModelMultipleChoiceField(
    queryset=MailingList.objects.filter(
        list_active=True),
    widget=forms.CheckboxSelectMultiple(
        {'class': 'no-bullet-list',
         'style': 'list-style: none;'}))
# Specifying class and style both is excessive, I'm still exploring.
 

Между тем, я поместил это в свой CSS-лист:

 .no-bullet-list {
    list-style-type: none;
}
 

Это делает то, что я хочу, отображая правильный набор вариантов в виде флажков, но также ставит перед ними маркеры. Это потому, что отображаемый HTML-код выглядит следующим образом:

 <ul id="id_newsletters" class="no-bullet-list">
  <li><label for="id_newsletters_0">
      <input type="checkbox" name="newsletters" value="1"
       class="no-bullet-list" style="list-style: none;"
       id="id_newsletters_0">
  Annonces</label>
</li>
 

Этот фрагмент взят из django/forms/templates/django/forms/widgets/multiple_input.html , который является результатом определения CheckboxSelectMultiple in django/forms/widgets.py .

 class CheckboxSelectMultiple(ChoiceWidget):
    allow_multiple_selected = True
    input_type = 'checkbox'
    template_name = 'django/forms/widgets/checkbox_select.html'
    option_template_name = 'django/forms/widgets/checkbox_option.html'

    def use_required_attribute(self, initial):
        # Don't use the 'required' attribute because browser validation would
        # require all checkboxes to be checked instead of at least one.
        return False

    def value_omitted_from_data(self, data, files, name):
        # HTML checkboxes don't appear in POST data if not checked, so it's
        # never known if the value is actually omitted.
        return False

    def id_for_label(self, id_, index=None):
        """"
        Don't include for="field_0" in <label> because clicking such a label
        would toggle the first checkbox.
        """
        if index is None:
            return ''
        return super().id_for_label(id_, index)
 

Моя попытка добавить атрибуты CSS к <li> единственному преуспела в добавлении к <ul> и к <input ...> , поэтому он не делает то, что я хочу (удалите маркеры). Кроме того, похоже, что для стилизации нет хука настройки <li> .

Единственный способ, который я вижу для этого, — скопировать полное определение виджета и его шаблон в мое приложение и изменить их. Это отвратительно. Есть ли переносимый способ оформления элементов списка флажков?

FWIW, мой собственный шаблон делает это:

     <form method="post">{% csrf_token %}
    <p>{{ form.non_field_errors }}</p>
    {% for field in form %}
    <p>
        {{ field.label }}<br>
        {{ field }}
        {% if field.help_text %}
        <small style="color: grey">{{ field.help_text }}</small>
        {% endif %}
    </p>
    {% for error in field.error_messages %}
    <p style="color: red">{{ error }}</p>
    {% endfor %}
    {% endfor %}

    <button type="submit" class="btn btn-outline-primary">Je m'inscris</button>
    </form>
 

Комментарии:

1. Вы уверены, что правильно загрузили css? Из-за кэширования это само по себе не так.

Ответ №1:

Ваш forms.py должно сработать. Пара шагов, которые нужно предпринять для отладки:

  1. очистите историю браузера. Я помню, что был крайне разочарован css, и оказалось, что у них были проблемы с кэшированием.
  2. Если шаг 1) не работает, откройте инструменты разработки Chrome и посмотрите, загружается ли ваш css. Если вы получите что-то вроде приведенного ниже: GET http://127.0.0.1:8000/static/soforms/css/soforms.css
    net:: ERR_ABORTED 404 (Not Found) .

2-1) затем попытайтесь убедиться, что у вас есть

 STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR.joinpath('static_files')
 

2-2) проверьте css , находится ли ваш файл в нужном месте.

2-3) в редком случае это может быть связано с тем, что вы забыли migrate после создания вашего app . Это действительно случилось со мной сегодня.

Комментарии:

1. Действительно, это был кеш браузера. Выполнение перезагрузки сдвига в браузере отсортировало это. Спасибо!