Анкета в стиле Лайкерта с Django radioSelect в виде таблицы html - PullRequest
0 голосов
/ 26 июня 2018

В настоящее время я занимаюсь разработкой веб-сайта с несколькими анкетами в формате html-таблицы.Предполагается, что на вопросники должны быть ответы в стиле Likert с переключателями.Для этого я пытаюсь отобразить виджет «radioSelect» в виде таблицы html вместо стандартного формата списка.Я хотел бы, чтобы это выглядело так:

|----------|---------|-----------|---------|----------|
|          |  Never  | Sometimes |  Often  |  Always  |
|----------|---------|-----------|---------|----------|
| Question | First 0 | Second 0  | Third 0 | Fourth 0 |
|----------|---------|-----------|---------|----------|
| Question | First 0 | Second 0  | Third 0 | Fourth 0 |
|----------|---------|-----------|---------|----------|

...

|----------|---------|-----------|---------|----------|
| Question | First 0 | Second 0  | Third 0 | Fourth 0 |
|----------|---------|-----------|---------|----------|

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

<td><label for="id_choice_field_0"><input type="radio" name="choice_field" value="1" id="id_choice_field_0" required />First</label></td>
<td><label for="id_choice_field_1"><input type="radio" name="choice_field" value="2" id="id_choice_field_1" required />Second</label></td>
...
<td><label for="id_choice_field_n"><input type="radio" name="choice_field" value="n" id="id_choice_field_n" required />n</label></td>

Я пытался вычислитькак это сделать, основываясь на ответах от этой угрозы от 7 лет назад.Я все еще новичок, и с тех пор многое изменилось в Django, поэтому я, к сожалению, не смог заставить его работать.

Я также играл с css на основе этой нити иЯ пытался использовать «as_table» в своем html-коде, но у меня тоже ничего не получалось.

От прохождения всех других угроз, которые казались относящимися к моей проблеме, и от прочтения документации я понимаю, что долженпереопределите средство визуализации по умолчанию 'radioSelect' с моим собственным настраиваемым средством визуализации, чтобы заменить теги списка тегами таблицы.Исходя из этого предположения, я предпринял следующую попытку:

forms.py:

from django import forms
from django.utils.safestring import mark_safe

class MyCustomRenderer(forms.RadioSelect):
    def render(self):
        return( mark_safe( u''.join( [ u'<td>%s</td>' % force_unicode(w.tag()) for w in self ] )))

CHOICES = (('1', 'First',),('2', 'Second',),('3', 'Third',),('4', 'Fourth',))

class SelectForm(forms.Form):
    choice_field = forms.ChoiceField(widget=forms.RadioSelect(renderer=MyCustomRenderer), choices=CHOICES, label='TEST')

views.py:

from django.shortcuts import render, HttpResponse
from django.views.generic import TemplateView
from accounts.forms import SelectForm

class HomeView(TemplateView):
    template_name = 'accounts/formtest.html'

    def get(self, request):
        form = SelectForm() 
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = SelectForm(request.POST)
        if form.is_valid():
        text = form.cleaned_data['choice_field']

        args = {'form': form, 'text': text}
        return render(request, self.template_name, args)

formtest.html:

{% extends 'base.html' %}

{% block body %}
<h1>Form test</h1>

<form method="post">
    {% csrf_token %}
    <table>
        <thead>
            <tr>
                <th></th>
                <th>Never</th>
                <th>Sometimes</th>
                <th>Often</th>
                <th>Always</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                {% for radio in form %}
                <td class="question_align">Question<td>
                        {{ radio }}
                {% endfor %}
            </tr>
        </tbody>
    </table>

    <button type="submit">Submit</button>

</form>

<br>

<h1>{{ text }}</h1>
{% endblock %}

Мне удалось обработать несколько сообщений об ошибках, но я застрял при появлении следующего сообщения об ошибке:

TypeError: __init__() получил неожиданный аргумент ключевого слова 'renderer'

Я предполагаю, что эта ошибка относится к атрибуту виджета.Однако я не понимаю, как исправить эту ошибку, так как я думал, что атрибут 'renderer' необходим для переопределения рендерера по умолчанию.

Я был бы очень признателен за любую помощь в этом.Если я иду в неправильном направлении, есть ли лучший способ добиться этого, может быть?

PS: Хотя я много раз обращался к StackOverflow, я впервые задаю вопрос сам.Любые отзывы о том, как улучшить мой вопрос, очень приветствуются!

1 Ответ

0 голосов
/ 12 июля 2018

В конце концов я нашел ответ на свой вопрос в документации Django.Оказывается, что подход, который я подробно описал в своем вопросе, устарел и не будет работать в последних версиях Django.Команда, которая разрабатывает Django, создала гораздо более элегантный и простой метод: вместо переопределения рендерера в вашем forms.py, вы должны использовать язык шаблонов Django в своем HTML-файле.Он описан здесь .

. Я поиграюсь с этим больше (и обновлю свой ответ, если я считаю, что это важно добавить), но, насколько я понял, вы должны:

1) указать поле по имени при вызове формы;
2) добавить необходимые теги вручную;
3) использовать атрибут тега radiobutton.

Вот код, который работает для меня:

{% extends 'base.html' %}

{% block body %}
<h1>Form test</h1>

<form method="post">
    {% csrf_token %}
    <table>
        <thead>
            <tr>
                <th></th>
                <th>Never</th>
                <th>Sometimes</th>
                <th>Often</th>
                <th>Always</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="question_align">Question<td>
                {% for radio in form.choice_field %}
                    <td class="question_align">{{ radio.tag }}</td>
                {% endfor %}
            </tr>
        </tbody>
    </table>

    <button type="submit">Submit</button>

</form>

<br>

<h1>{{ text }}</h1>
{% endblock %}

Это довольно очевидно, когда вы это знаете.

В любом случае, надеюсь, что это кому-нибудь поможет!

...