Поля формы Django появляются динамически - PullRequest
0 голосов
/ 30 ноября 2018

В моем приложении Django есть форма, которая содержит более 20 полей.Было запрошено, чтобы у меня отображались только первые несколько полей.После того, как эти поля заполнены, должны появиться следующие несколько полей, в дополнение к предыдущим полям.Как я могу это сделать?

Ниже приведены мои forms.py

class QuoteForm(forms.Form):
    premium_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Premium Admin Stations Needed'}))
    standard_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Standard Admin Stations Needed'}))
    basic_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Basic Admin Stations Needed'}))
    messaging_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Messaging Stations Needed'}))
    auto_attendant = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Auto Attendants Needed'}))
    toll_service = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Toll-Free Services Needed'}))
    receptionist = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Receptionist Clients Needed'}))
    group_paging = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Group Paging Needed'}))
    FourG_backup = forms.IntegerField(max_value=2000, min_value=0,  required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# 4G Backups Needed'}))
    broadsoft_hub = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# BroadSoft Hubs Needed'}))
    polycom_410 = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Polycom VVX 410 Needed'}))
    spa_122 = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Linksys SPA122 Needed'}))
    yealink = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Yealink W52P POE Needed'}))

Мои Views.py:

def quote(request, phonenumber):
    if request.method=='POST':
        quote = PBXQuote.objects.filter(phone_number=phonenumber).order_by('id').last()
        quote.premium_station = request.POST.get('premium_station')
        quote.standard_station = request.POST.get('standard_station')
        quote.basic_station = request.POST.get('basic_station')
        quote.messaging_station = request.POST.get('messaging_station')
        quote.auto_attendant = request.POST.get('auto_attendant')
        quote.hunt_group = request.POST.get('hunt_group')
        quote.toll_service = request.POST.get('toll_service')
        quote.music_hold = request.POST.get('music_hold')
        quote.call_recording = request.POST.get('call_recording')
        quote.receptionist = request.POST.get('receptionist')
        quote.group_paging = request.POST.get('group_paging')
        quote.FourG_backup = request.POST.get('FourG_backup')
        quote.broadsoft_hub = request.POST.get('broadsoft_hub')
        quote.polycom_410 = request.POST.get('polycom_410')
        quote.spa_122 = request.POST.get('spa_122')
        quote.yealink = request.POST.get('yealink')
        quote.ported_nums = request.POST.get('ported_nums')
        quote.new_nums = request.POST.get('new_nums')
        quote.directory_listing = request.POST.get('directory_listing')
        quote.save()
        return redirect('../../viewpbxquote/{}/'.format(phonenumber))


    else:
        form = PBXQuoteForm()
    context = {'form' : form}
    return render(request, 'Home/pbxquote.html', context)

И раздел формы из моего HTML-файла:

            <section id="quote-section">
                    <div id="order-form-container">
                            <form class="login" method="post">
                                    {% csrf_token %}
                                    <h1>Quote</h1>
                                    <h2>Hosted Stations</h2>
                                    <div class="form-group">
                                            <label for="premium_station" class="sr-only">Premium Stations</label>
                                            {{ form.premium_station }} Monthly: $32.00 | One-Time: $8.00 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="standard_station" class="sr-only">Standard Stations</label>
                                            {{ form.standard_station }} Monthly: $25.00 | One-Time: $8.00 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="basic_station" class="sr-only">Basic Stations</label>
                                            {{ form.basic_station }} Monthly: $14.00 | One-Time: $8.00 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="messaging_station" class="sr-only">Messaging Stations</label>
                                            {{ form.messaging_station }} Monthly: $4.95 | One-Time: N/A Each
                                    </div><!--Ideally, this would be where the first displayed section would end. As long as at least one of these values changes, the next section would appear, as it shouldn't be necessary for every field unwanted to be set to '0'.-->
                                    <h2>Services</h2>
                                    <div class="form-group">
                                            <label for="auto_attendant" class="sr-only">Auto Attendants</label>
                                    <div class="form-group">
                                            <label for="hunt_group" class="sr-only">Hunt Group Package</label>
                                            <select class="form-control" name="hunt-group">
                                                    <option disabled selected>Hunt Group</option>
                                                    <option value="1">Yes</option>
                                                    <option value="0">No</option>
                                            </select>
                                            <span>Monthly: N/A | One-Time: N/A</span>
                                    </div>
                                    <div class="form-group">
                                            <label for="toll_service" class="sr-only">Toll-Free Services</label>
                                            {{ form.toll_service }} Monthly: $4.95 | One-Time: $14.95 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="music_hold" class="sr-only">Music On Hold</label>
                                            <select class="form-control" name="music_hold">
                                                    <option disabled selected>Music On Hold</option>
                                                    <option value="1">Yes</option>
                                                    <option value="0">No</option>
                                            </select>
                                            <span>Monthly: $9.95 | One-Time: N/A </span>
                                    </div>
                                    <div class="form-group">
                                            <label for="call_recording" class="sr-only">
                                            <select class="form-control" class="sr-only">
                                                    <option disabled selected>Call Recording</option>
                                                    <option value="1">Yes</option>
                                                    <option value="0">No</option>
                                            </select>
                                            <span>Monthly: $9.95 | One-Time: N/A </span>
                                    </div>
                                    <div class="form-group">
                                            <label for="receptionist" class="sr-only">Receptionist Clients</label>
                                            {{ form.receptionist }} Monthly: $9.95 | One-Time: $14.95 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="group_paging" class="sr-only">Group Paging</label>
                                            {{ form.group_paging }} Monthly: $9.95 | One-Time: $14.95 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="FourG_backup" class="sr-only">4G LTE Backup</label>
                                            {{ form.FourG_backup }} Monthly: $75.00 | One-Time: N/A Each
                                    </div>
                                    <div class="form-group">
                                            <label for="broadsoft_hub" class="sr-only">BroadSoft Hub</label>
                                            {{ form.broadsoft_hub }} Monthly: $2.00 | One-Time: N/A Each
                                    </div><!--The second section would end here. This time, every field that is a select would either be selected "Yes" or "No", and the next section would appear.-->
                                    <h2>Equipment</h2>
                                    <div class="form-group">
                                    <div class="form-group">
                                            <label for="polycom_410" class="sr-only">Polycom VVX 410</label>
                                            {{ form.polycom_410 }} One-Time: $144.00 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="spa_122" class="sr-only">Linksys SPA-122 ATA</label>
                                            {{ form.spa_122 }} One-Time: $34.90 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="yealink" class="sr-only">Yealink W52P</label>
                                            {{ form.yealink }} One-Time: $129.00 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="ported_nums" class="sr-only">Ported Numbers</label>
                                            {{ form.ported_nums }} Monthly: N/A | One-Time: $9.95 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="new_nums" class="sr-only">New Numbers</label>
                                            {{ form.new_nums }} Monthly: $1.00 | One-Time: $1.95 Each
                                    </div>
                                    <div class="form-group">
                                            <label for="directory_listing" class="sr-only">Directory Listings</label>
                                            {{ form.directory_listing }} Monthly: $10.00 | One-Time: $20.00 Each
                                    </div>
                                    </div>
                                    <button class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
                            </form>
                    </div>
            </section>

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

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Вы можете использовать мастер форм для этого.Он создает чистые формы, которые делают именно то, что вам нужно, и все это с помощью Django и python, без javascript.

Сначала добавьте инструменты формы в установленные приложения.

Создайте несколько форм вместо одной:

class QuoteForm1(forms.Form):
    premium_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Premium Admin Stations Needed'}))
    standard_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Standard Admin Stations Needed'}))
    basic_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Basic Admin Stations Needed'}))

class QuoteForm2(forms.Form):
    messaging_station = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Messaging Stations Needed'}))
    auto_attendant = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Auto Attendants Needed'}))
    toll_service = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Toll-Free Services Needed'}))

class QuoteForm3(forms.Form):
    receptionist = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Receptionist Clients Needed'}))
    group_paging = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Group Paging Needed'}))
    FourG_backup = forms.IntegerField(max_value=2000, min_value=0,  required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# 4G Backups Needed'}))
    broadsoft_hub = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# BroadSoft Hubs Needed'}))

class QuoteForm4(forms.Form):
    polycom_410 = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Polycom VVX 410 Needed'}))
    spa_122 = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Linksys SPA122 Needed'}))
    yealink = forms.IntegerField(max_value=2000, min_value=0, required=False, widget = forms.NumberInput(attrs={'class' : 'form-control', 'placeholder' : '# Yealink W52P POE Needed'}))

Затем в своих представлениях вы импортируете из SessionWizardView и указываете формы:

from formtools.wizard.views import SessionWizardView

class QuoteFormView(SessionWizardView):
    instance_dict = None
    form_list = [QuoteForm1, QuoteForm2, QuoteForm3, QuoteForm4]
    template_name = 'quote_form.html'

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

TEMPLATES = {
            '0': 'quote_form1.html',
            '1': 'quote_form2.html',
            '2': 'quote_form3.html',
            '3': 'quote_form4.html',
            }

Добавьте get_template_names к вашему представлению:

def get_template_names(self):
    return [TEMPLATES[self.steps.current]]

Вместо обычного form.is_valid вы используете метод done для сохранения формы:

def done(self, form_list, **kwargs):
    data = {k: v for form in form_list for k, v in form.cleaned_data.items()}
    # Reference your data 
    attribute = data['premium_station']
    return HttpResponseRedirect('/redirect/')

И в вашем шаблоне должна быть форма управления, иначе она не будет работать:

{% extends "base.html" %}
{% load i18n %}

{% block head %}
{{ wizard.form.media }}
{% endblock %}

{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
    {{ wizard.form.management_form }}
    {% for form in wizard.form.forms %}
        {{ form }}
    {% endfor %}
{% else %}
    {{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>
</form>
{% endblock %}

Для справки

https://django -formtools.readthedocs.io /ан / последний / wizard.html #

0 голосов
/ 30 ноября 2018

Вы можете иметь две формы, одну для первой половины поля, а другую для остальных.Затем вы просто контролируете, какую форму вы передаете шаблону.Не сделал этого, но не кажется слишком сложным.Другой вариант - использовать Javascript для скрытия полей до тех пор, пока первая половина не будет заполнена, затем отобразить второй фрагмент и скрыть первый.

...