如何在不使用表单向导验证表单的情况下转到上一步

时间:2013-08-29 12:53:34

标签: django django-forms django-1.5 django-formwizard

我有一个使用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 %}

2 个答案:

答案 0 :(得分:1)

也许会帮助别人。

我正在使用带有引导程序的https://django-formtools.readthedocs.io/en/latest/wizard.html和Django。我遇到了与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 %}

希望有帮助。

答案 1 :(得分:0)

HTML5包含formnovalidate attribute,可用于跳过验证。对于“表单向导”,要跳过上一步的验证,只需将formnovalidate属性包括在相应的按钮中即可。例如(摘录自documentation的片段):

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