forms.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. from django import forms
  2. from django.contrib.auth import authenticate, login
  3. from django.contrib.auth.models import User
  4. from django.contrib.sites.models import Site
  5. from django.utils.translation import ugettext_lazy as _
  6. from . import models
  7. from . import profile as profile_utils
  8. from . import constants
  9. from . import utils
  10. REQUIRED = (u"There was missing information on your order. Please correct "
  11. u"the errors below.")
  12. class BasePersonForm(forms.Form):
  13. """ There's a common theme of form data for person information. """
  14. first_name = forms.CharField(
  15. label=_(u'First name'), max_length=30, required=True,
  16. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  17. last_name = forms.CharField(
  18. label=_(u'Last name'), max_length=30, required=True,
  19. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  20. company = forms.CharField(
  21. label=_(u'Company'), max_length=30, required=False,
  22. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  23. address1 = forms.CharField(
  24. label=_(u'Address 1'), max_length=30, required=True,
  25. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  26. address2 = forms.CharField(
  27. label=_(u'Address 2'), max_length=30, required=False,
  28. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  29. city = forms.CharField(
  30. label=_(u'City'), max_length=30, required=True,
  31. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  32. region = forms.CharField(
  33. label=_(u'Region'), max_length=30, required=True,
  34. widget=forms.Select(choices=constants.STATE_CHOICES, attrs={
  35. 'width': '100px', 'onchange': "calculate_price();"}))
  36. country = forms.CharField(
  37. label=_(u'Country'), max_length=50, required=True,
  38. widget=forms.Select(choices=constants.COUNTRIES, attrs={
  39. 'onchange': "check_state(); calculate_price();"}))
  40. country_other = forms.CharField(
  41. label=_(u'Other'), max_length=30, required=False,
  42. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  43. postal_code = forms.CharField(
  44. label=_(u'Postal Code'), max_length=15, required=True,
  45. widget=forms.TextInput(attrs={
  46. 'type': 'text', 'size': 15, 'onchange': "calculate_price();"}))
  47. plus_four = forms.CharField(
  48. label=_(u'Plus Four'), max_length=15, required=False,
  49. widget=forms.TextInput(attrs={'type': 'text', 'size': 15}))
  50. phone = forms.CharField(
  51. label=_(u'Phone'), max_length=30, required=True,
  52. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  53. class EmailRequiredPersonForm(BasePersonForm):
  54. """ In some cases, we need the email address to be required """
  55. email = forms.EmailField(
  56. label=_(u"Email"), max_length=30, required=True,
  57. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  58. class EmailNotRequiredPersonForm(BasePersonForm):
  59. """ In some cases, we need the email address to not be required """
  60. email = forms.EmailField(
  61. label=_(u"Email"), max_length=30, required=False,
  62. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  63. class NonRequiredBasePersonForm(forms.Form):
  64. first_name = forms.CharField(
  65. label=_(u'First name'), max_length=30, required=False,
  66. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  67. last_name = forms.CharField(
  68. label=_(u'Last name'), max_length=30, required=False,
  69. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  70. company = forms.CharField(
  71. label=_(u'Company'), max_length=30, required=False,
  72. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  73. address1 = forms.CharField(
  74. label=_(u'Address 1'), max_length=30, required=False,
  75. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  76. address2 = forms.CharField(
  77. label=_(u'Address 2'), max_length=30, required=False,
  78. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  79. city = forms.CharField(
  80. label=_(u'City'), max_length=30, required=False,
  81. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  82. region = forms.ChoiceField(
  83. label=_(u'Region'), required=False,
  84. choices=constants.STATE_CHOICES,
  85. widget=forms.Select(choices=constants.STATE_CHOICES, attrs={
  86. 'onchange': "calculate_price();"}))
  87. country = forms.ChoiceField(
  88. label=_(u'Country'), required=False,
  89. choices=(('', '----------'),) + constants.COUNTRIES,
  90. widget=forms.Select(choices=constants.STATE_CHOICES, attrs={
  91. 'onchange': "check_state(); calculate_price();"}))
  92. country_other = forms.CharField(
  93. label=_(u'Other'), max_length=30, required=False,
  94. widget=forms.TextInput(attrs={'type': 'text', 'size': 25}))
  95. postal_code = forms.CharField(
  96. label=_(u'Postal Code'), max_length=15, required=False,
  97. widget=forms.TextInput(attrs={
  98. 'type': 'text', 'size': 15, 'onchange': "calculate_price();"}))
  99. plus_four = forms.CharField(
  100. label=_(u'Plus Four'), max_length=4, required=False,
  101. widget=forms.TextInput(attrs={'type': 'text', 'size': 15}))
  102. phone = forms.CharField(
  103. label=_(u'Phone'), max_length=30, required=False,
  104. widget=forms.TextInput(attrs={'type': 'text', 'size': 50}))
  105. class ProfileCreateForm(EmailRequiredPersonForm):
  106. """ Form used for creating a new user """
  107. password1 = forms.CharField(
  108. label=_("Password"), widget=forms.PasswordInput, required=True)
  109. password2 = forms.CharField(
  110. label=_("Password confirmation"), widget=forms.PasswordInput,
  111. required=True)
  112. def save(self, request=None):
  113. """ Creates a new user and account. Returns the newly created user. """
  114. password = self.cleaned_data['password1']
  115. username, email, password = (self.cleaned_data['email'],
  116. self.cleaned_data['email'],
  117. password)
  118. user = User.objects.create_user(username, email, password)
  119. user.first_name = self.cleaned_data['first_name']
  120. user.last_name = self.cleaned_data['last_name']
  121. user.save()
  122. profile = profile_utils.get_profile(user)
  123. profile.company = self.cleaned_data['company']
  124. profile.address1 = self.cleaned_data['address1']
  125. profile.address2 = self.cleaned_data['address2']
  126. profile.city = self.cleaned_data['city']
  127. profile.region = self.cleaned_data['region']
  128. profile.phone = self.cleaned_data['phone']
  129. profile.country = self.cleaned_data['country']
  130. profile.postal_code = self.cleaned_data['postal_code']
  131. profile.plus_four = self.cleaned_data['plus_four']
  132. profile.save()
  133. user = authenticate(username=username, password=password)
  134. if request:
  135. login(request, user)
  136. site = Site.objects.get_current()
  137. utils.send_new_account_email(email, password, user, profile, site)
  138. return user
  139. def clean(self):
  140. # We want a single error message. We don't display the validation
  141. # errors for each part of the form
  142. for field in self.fields:
  143. if self.fields[field].required and not self.cleaned_data.get(
  144. field, None):
  145. raise forms.ValidationError(_(REQUIRED))
  146. self.clean_email()
  147. return self.cleaned_data
  148. def clean_email(self):
  149. """ Validate that the e-mail address is unique. """
  150. if (User.objects.filter(
  151. email__iexact=self.cleaned_data['email']) or
  152. User.objects.filter(
  153. username__iexact=self.cleaned_data['email'])):
  154. raise forms.ValidationError(_(
  155. 'This email is already in use. '
  156. 'Please supply a different email.'))
  157. return self.cleaned_data['email']
  158. def clean_password2(self):
  159. password1 = self.cleaned_data.get("password1", "")
  160. password2 = self.cleaned_data["password2"]
  161. if password1 != password2:
  162. raise forms.ValidationError(
  163. "Your passwords did not match. Please re-enter your passwords.")
  164. return password2
  165. class ProfileUpdateForm(EmailRequiredPersonForm):
  166. """
  167. A form to demonstrate how to add extra fields to the signup form, in this
  168. case adding the first and last name.
  169. """
  170. def __init__(self, user, *args, **kwargs):
  171. self.user = user
  172. super(ProfileUpdateForm, self).__init__(*args, **kwargs)
  173. def clean_email(self):
  174. """ Validate that the email is not already registered with another user
  175. """
  176. if User.objects.filter(
  177. email__iexact=self.cleaned_data['email']).exclude(
  178. email__iexact=self.user.email):
  179. raise forms.ValidationError(_(
  180. u'This email is already in use. Please supply a different '
  181. u'email.'))
  182. return self.cleaned_data['email']
  183. def save(self, request=None):
  184. """
  185. Override the save method to save the first and last name to the user
  186. field.
  187. """
  188. user = self.user
  189. user.first_name = self.cleaned_data['first_name']
  190. user.last_name = self.cleaned_data['last_name']
  191. user.email = self.cleaned_data['email']
  192. user.save()
  193. profile = profile_utils.get_profile(user)
  194. profile.company = self.cleaned_data['company']
  195. profile.address1 = self.cleaned_data['address1']
  196. profile.address2 = self.cleaned_data['address2']
  197. profile.city = self.cleaned_data['city']
  198. profile.region = self.cleaned_data['region']
  199. profile.phone = self.cleaned_data['phone']
  200. profile.country = self.cleaned_data['country']
  201. profile.country_other = self.cleaned_data['country_other']
  202. profile.postal_code = self.cleaned_data['postal_code']
  203. profile.plus_four = self.cleaned_data['plus_four']
  204. profile.save()
  205. # Userena expects to get the new user from this form, so return the new
  206. # user.
  207. return user
  208. class ProfileSecondaryAddressForm(NonRequiredBasePersonForm):
  209. address_from = forms.DateField(required=False)
  210. address_to = forms.DateField(required=False)
  211. class Meta:
  212. model = models.SecondaryProfileAddress
  213. exclude = ('profile')
  214. def __init__(self, *args, **kw):
  215. super(ProfileSecondaryAddressForm, self).__init__(*args, **kw)
  216. def save(self, *args, **kwargs):
  217. user = kwargs.pop('user', None)
  218. profile_address = profile_utils.get_profile_secondary_address(user)
  219. profile_address.profile = profile_utils.get_profile(user)
  220. for k, v in self.cleaned_data.iteritems():
  221. setattr(profile_address, k, v)
  222. profile_address.save()
  223. return profile_address