forms.py 11 KB

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