3

我有一个使用 django 表单向导构建的多步骤表单sessionwizardview,我添加了下一个和上一个按钮,但问题是,如果我在一个步骤中并且当我单击上一个时,它会要求先填写表单然后可以继续并通过单击上一个按钮转到上一步。我一无所知,因为我找不到与我的问题相关的任何东西,我错过了什么吗?

以下是几个示例表格:

    from django import forms
    from django.utils.translation import gettext as _

    from addresses.forms import AddressForm, InvoiceAddressForm
    from core.api import NcpAPI
    from django_countries import countries

    api = NcpAPI()
    CHOICES=[('0','Pay by card'), ('1','Invoice')]

    class RegistrationForm(forms.Form):
        title = 'registration'
        first_name      = forms.CharField(label=_("First Name"), widget=forms.TextInput(attrs={'class':'form-text required'}))
        last_name       = forms.CharField(label=_("Last Name"), widget=forms.TextInput(attrs={'class':'form-text required'}))
        registration_company        = forms.CharField(label=_("Company"), widget=forms.TextInput(attrs={'class':'form-text required'}))
        phone           = forms.CharField(label=_("Phone"), widget=forms.TextInput(attrs={'class':'form-text required'}))
        email           = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'class':'form-text required'}))

        def clean_email(self):
            email = self.cleaned_data.get('email')
            if api.is_username_taken(email):
                raise forms.ValidationError(_('Email is in use'))
            return email
class AddressesForm(InvoiceAddressForm, AddressForm):
    title = 'addresses'

class PaymentForm(forms.Form):
    title = 'payment'
    payment_method = forms.ChoiceField(label = _("Payment Options"), choices=CHOICES, widget=forms.RadioSelect(attrs={'class':'form-text required'}), required = True, initial = "1")


class ConfirmationForm(forms.Form):
    title = 'confirm'

这是我的会话向导类:

class SubscriptionWizard(SessionWizardView):
    def get_template_names(self):
        return [TEMPLATES.get(self.steps.current)]

    extra_data = {}
    def get_context_data(self, form, **kwargs):
        pp = pprint.PrettyPrinter(indent=4)
        context = super(SubscriptionWizard, self).get_context_data(form=form, **kwargs)
        context.update(self.extra_data)
        data  = self.get_all_cleaned_data()


        context['all_data'] = {"product":self.kwargs['product']}
        # if self.steps.current == 'addresses':
        #     print ' yes its addresses %s' % data.get('company')
        #     context['all_data'].update({"reg_company":data.get('company')})

        if self.steps.current in ('payment', 'confirm'):
            if data[u'invoice_name'] != '':
                p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(str(data[u'invoice_country']))) )
            else:
                p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(data.get('country'))) )

            context['all_data']['product_price'] = p[0].price
            context['all_data']['product_currency'] = p[0].currency
            if data.get('invoice_name'):
                currency_country = data.get('invoice_country')
            else:
                currency_country = data.get('country')

        if self.steps.current == 'confirm':

            p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(data.get('country'))) )
            context['all_data']['product_price'] = p[0].price
            context['all_data']['product_currency'] = p[0].currency

        if data:
            # pp.pprint(data)
            context['all_data'].update(data)
            # pp.pprint(context['all_data'])
        return context

    def get_form_initial(self, step):
        initial = self.initial_dict.get(step, {})
        if 'profiler' in self.request.session and step in ('registration', 'address', 'payment'):
            profiler = self.request.session.get('profiler')

            data = {}
            if step == 'registration':
                # pp = pprint.PrettyPrinter(indent=4)
                # pp.pprint(profiler.user.account.account)
                # print profiler.user.account
                data = {'email': profiler.user.account.email , 
                        'first_name':profiler.user.account.firstName if profiler.user.account.account.firstName != '' else '', 
                        'last_name':profiler.user.account.lastName, 
                        'phone': profiler.user.account.phone1 if profiler.user.account.account.firstName != '' else ''}
            initial.update(data)
        return initial

    def get_form(self, step=None, data=None, files=None):
        form = super(SessionWizardView, self).get_form(step, data, files)
        if hasattr(form, 'initialize_wizard'):
            form.initialize_wizard(self)
        return form

    def getCurrencyCode(self, countryCode):
        continent = transformations.cca_to_ctn(countryCode)
        # print continent
        if str(countryCode) == 'NO':
            return 'NOK'

        if str(countryCode) == 'GB':
            return 'GBP'

        if (continent == 'Europe') or (continent == 'Africa'):
            return 'EUR'

        return 'USD'

    def done(self, form_list, **kwargs):
        pp = pprint.PrettyPrinter(indent=4)
        import hashlib
        data = dict(('%s_%s' % (form.prefix,k),v) for form in form_list for k, v in form.cleaned_data.items())

        # print 'print data ....'
        # print ''
        # print ''
        # pp.pprint(data)
        # print ''
        # print ''
        # print ''
        # print '--------------'


        # print data
        full_name = "%s %s" % (data['registration_first_name'],data['registration_last_name'])
        data['product'] = kwargs['product']

        dumps = simplejson.dumps(data)
        data['country_label']=unicode(fields.Country(data['addresses_country']).name)
        print data
        if data.get('invoice_name'):
            currency_country = data.get('addresses_invoice_country')
        else:
            currency_country = data.get('addresses_country')
        currencyCode = self.getCurrencyCode(currency_country)
        prices = Prices.objects.filter(name = kwargs['product'], currency = str(currencyCode))
        data['product_price'] = prices[0].price
        data['product_currency'] = str(currencyCode)
        # print currencyCode
        include_archive = 'standard' in kwargs.values()

        # Register.
        # print 'print data before registering the product ....'
        # print ''
        # print ''
        # pp.pprint(data)
        # print ''
        # print ''
        # print ''
        # print '--------------'
        result = api.subscribe_to_product(subscribe_to_archive=include_archive, **data)
        if 'errorCode' in result:
            messages.add_message(self.request, messages.ERROR, _('The registration was not successfull.'))
            return render(self.request, 'subscription_product/failed.html', {'clean_data': data})


        print '--------'
        cs_message = render_to_string(
                'subscription_product/email/registered_cs.html', {'data':data})
        print api.email(settings.EMAIL_CS_NAME, settings.EMAIL_CS_EMAIL, "Registration for %s" % data['product'], cs_message)

        # Save subscription.
        s = SubscriptionInfo(subscriptionId = str(result[u'subscriptionId']), customerNumber = result[u'customerNumber'],subscriptionType = str(data['product']), currency = str(currencyCode))
        s.save()

        if int(data['payment_payment_method']) == 1:
            # Sends activation email.
            token = api.create_token(7200, 99,'productSub', data['registration_email']).get('tokenValue', '')
            activation_url = Site.objects.get_current().domain + reverse("activation_home", kwargs={'token':token})
            # activation_url = 'http://localhost:8080' + reverse("activation_home", kwargs={'token':token})
            # full_name = '%s %s' % (data.get('registration_first_name'), data.get('registration_last_name'))
            customer_message = render_to_string(
                'subscription_product/email/registered_customer.html', {'activation_url':activation_url})
            print api.email("%s %s" % (data['registration_first_name'], data['registration_last_name']), data['registration_email'], "Your Tradewindsnews.com order registration", customer_message)
            #SEND EMAIL TO SALES ON SUCCESS
            sales_message = render_to_string(
                    'subscription_product/email/invoice_sales_success.html', 
                    {'customer_name': full_name,
                    'account': data,
                    'alternative_invoice_company':data['addresses_invoice_company'],
                    'alternative_invoice_street':data['addresses_invoice_street'],
                    'alternative_invoice_city':data['addresses_invoice_city'],
                    'alternative_invoice_postal_code':data['addresses_invoice_postal_code'],
                    'alternative_invoice_country':data['addresses_invoice_country'],
                    'payment_date': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    'amount': float(prices[0].price),
                    'currency' : currencyCode,
                    'transactionid' :'',
                    'authorizationid' : '',
                    'confirmation_number': ''})
            api.email("%s %s" % (data['registration_first_name'], data['registration_last_name']), settings.EMAIL_SALES, "New Subscription Order", sales_message)

            return render(self.request, 'subscription_product/receipt.html', {'clean_data': data})

        else:
            site_url = "http://%s" % Site.objects.get(name='secondary')
            # site_url = "http://localhost:8000"
            # dumps = simplejson.dumps(data)
            p = PaymentBeforeDump(dump = dumps, subscriptionInfo = s)

            p.save()
            # prices = Prices.objects.get(name = kwargs['product'])

            return HttpResponseRedirect(
                Register(
                    p_request_Order_Amount = int(float(prices[0].price)*100),
                    p_request_Order_CurrencyCode = currencyCode,
                    p_request_Order_OrderNumber = hashlib.md5("foobar" + str(time.time())).hexdigest(),
                    p_request_Terminal_RedirectUrl = site_url + reverse("subscription_product_payment_return",kwargs={'amount':int(float(prices[0].price)*100), 'currency': str(currencyCode), 'subscription': kwargs['product'], 'id':p.id}),
                    p_request_TransactionReconRef =  'tw-random',
                )
            )

这是一个模板:

{% extends "base.html" %}
{% load url from future %}
{% load i18n %}
{% load subscription_product_tags %}

{% block content %}
<section class="topsection group">
    <div class="col span_3_of_3 first-child last-child">
        <div class="order">
            <ol class="steps">
                <li class="done">Subscription</li>
                <li class="done">Details</li>
                <li class="done">Delivery</li>
                <li class="active">Payment</li>
                <li class="queue">Confirm</li>
                <li class="queue">Receipt</li>
            </ol>

            <div class="box">
                <section class="section group first-child">
                    <h1>Payment Summary</h1>
                    Please review the following details for this transaction.
                </section>
                <section class="topsection group">
                    <table border="1">
                        <tr>
                            <th>
                                Description
                            </th>
                            <th>
                                Item Price
                            </th>
                        </tr>
                        <tr>
                                {% comment %}get the pricing and other product related info{% endcomment %}
                                {{ all_data|product_price_info|safe }}
                        </tr>
                    </table>

                </section>
                 <form action="" method="post">{% csrf_token %}
                        {{ wizard.management_form }}
                        {% if wizard.form.forms %}
                            {{ wizard.form.management_form }}
                            {% for form in wizard.form.forms %}
                                {{ form }}
                            {% endfor %}
                        {% else %}
                            <section class="topsection group">

                                {{ wizard.form.payment_method.label_tag }}
                                {{wizard.form.payment_method}}
                                {{ wizard.form.payment_method.errors}}

                          </section>
                          {%endif %}
                        <section class="section group last-child">
                            <div class="col span_3_of_3 first-child last-child">
                                <fieldset class="form-actions">
                                    <!-- <a class="backbutton" onClick="goPrevious()">Previous</a> -->
                                   {# <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "Previous" %}</button> #}
                                   <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "Previous" %}</button>
                                    <input type="submit" value="Next">
                                </fieldset>
                            </div>
                        </section>

                 </form>
        </div>
        </div>
    </div>

</section>
{% endblock %}
{% block customerservice %}{% endblock %}
{% block footer %}{% endblock %}
4

3 回答 3

14

也许,它会帮助某人。

我正在使用 Django 和https://django-formtools.readthedocs.io/en/latest/wizard.html使用引导程序。我和 OP 有同样的问题,但我没有活跃的 JS。就我而言,解决方案是将formnovalidate="formnovalidate"添加到模板中。

{% if wizard.steps.prev %}
    <button formnovalidate="formnovalidate" name="wizard_goto_step" value="{{ wizard.steps.first }}">
        first step
    </button>
    <button formnovalidate="formnovalidate" name="wizard_goto_step" value="{{ wizard.steps.prev }}">
        prev step
    </button> {% endif %}

希望能帮助到你。

于 2018-11-06T20:59:06.403 回答
5

HTML5 包含可用于跳过验证的formnovalidate属性。在表单向导的情况下,要在转到上一步时跳过验证,只需将formnovalidate属性包含到相应的按钮中即可。例如(摘自文档的片段):

<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.form }}
</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 }}" formnovalidate>{% trans "prev step" %}</button>
{% endif %}


<input type="submit" value="{% trans "submit" %}"/>
</form>
于 2019-01-31T11:57:46.850 回答
3

这个问题是由于在 javascript 中完成的验证。与 django 表单向导或 django 本身无关。

您可能希望禁用它或在特定情况下跳过它。

于 2013-10-31T05:18:46.017 回答