Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango custom form field initial data
    text
    copied!<p>I am having trouble understanding how to initialize a custom form field in a django view. </p> <p>For example: <a href="http://djangosnippets.org/snippets/907/" rel="noreferrer">http://djangosnippets.org/snippets/907/</a></p> <pre><code>from datetime import date, datetime from calendar import monthrange class CreditCardField(forms.IntegerField): @staticmethod def get_cc_type(number): number = str(number) #group checking by ascending length of number if len(number) == 13: if number[0] == "4": return "Visa" return "Unknown" def clean(self, value): if value and (len(value) &lt; 13 or len(value) &gt; 16): raise forms.ValidationError("Please enter in a valid "+\ "credit card number.") elif self.get_cc_type(value) not in ("Visa", "MasterCard", "American Express"): raise forms.ValidationError("Please enter in a Visa, "+\ "Master Card, or American Express credit card number.") return super(CreditCardField, self).clean(value) class CCExpWidget(forms.MultiWidget): """ Widget containing two select boxes for selecting the month and year""" def decompress(self, value): return [value.month, value.year] if value else [None, None] def format_output(self, rendered_widgets): html = u' / '.join(rendered_widgets) return u'&lt;span style="white-space: nowrap"&gt;%s&lt;/span&gt;' % html class CCExpField(forms.MultiValueField): EXP_MONTH = [(x, x) for x in xrange(1, 13)] EXP_YEAR = [(x, x) for x in xrange(date.today().year, date.today().year + 15)] default_error_messages = { 'invalid_month': u'Enter a valid month.', 'invalid_year': u'Enter a valid year.', } def __init__(self, *args, **kwargs): errors = self.default_error_messages.copy() if 'error_messages' in kwargs: errors.update(kwargs['error_messages']) fields = ( forms.ChoiceField(choices=self.EXP_MONTH, error_messages={'invalid': errors['invalid_month']}), forms.ChoiceField(choices=self.EXP_YEAR, error_messages={'invalid': errors['invalid_year']}), ) super(CCExpField, self).__init__(fields, *args, **kwargs) self.widget = CCExpWidget(widgets = [fields[0].widget, fields[1].widget]) def clean(self, value): exp = super(CCExpField, self).clean(value) if date.today() &gt; exp: raise forms.ValidationError( "The expiration date you entered is in the past.") return exp def compress(self, data_list): if data_list: if data_list[1] in forms.fields.EMPTY_VALUES: error = self.error_messages['invalid_year'] raise forms.ValidationError(error) if data_list[0] in forms.fields.EMPTY_VALUES: error = self.error_messages['invalid_month'] raise forms.ValidationError(error) year = int(data_list[1]) month = int(data_list[0]) # find last day of the month day = monthrange(year, month)[1] return date(year, month, day) return None class PaymentForm(forms.Form): number = CreditCardField(required = True, label = "Card Number") holder = forms.CharField(required = True, label = "Card Holder Name", max_length = 60) expiration = CCExpField(required = True, label = "Expiration") ccv_number = forms.IntegerField(required = True, label = "CCV Number", max_value = 9999, widget = forms.TextInput(attrs={'size': '4'})) def __init__(self, *args, **kwargs): self.payment_data = kwargs.pop('payment_data', None) super(PaymentForm, self).__init__(*args, **kwargs) def clean(self): cleaned = super(PaymentForm, self).clean() if not self.errors: result = self.process_payment() if result and result[0] == 'Card declined': raise forms.ValidationError('Your credit card was declined.') elif result and result[0] == 'Processing error': raise forms.ValidationError( 'We encountered the following error while processing '+\ 'your credit card: '+result[1]) return cleaned def process_payment(self): if self.payment_data: # don't process payment if payment_data wasn't set datadict = self.cleaned_data datadict.update(self.payment_data) from virtualmerchant import VirtualMerchant vmerchant = VirtualMerchant(datadict) return vmerchant.process_virtualmerchant_payment() </code></pre> <p>In the above example payment form, how would you pass initial data to PaymentForm.expiration field? </p> <p>I know you can do:</p> <pre><code>c = PaymentForm({'number':'1234567890', 'holder':'Bob Barker','ccv_number':'123'}) </code></pre> <p>However, how do you pass data to a custom field such as the one implemented here? </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload