Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

views.py 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. from django.shortcuts import get_object_or_404, redirect
  2. from django.views import generic
  3. from django.core.urlresolvers import reverse, reverse_lazy
  4. from django.core.exceptions import ObjectDoesNotExist
  5. from django import http
  6. from django.contrib import messages
  7. from django.utils.translation import ugettext_lazy as _
  8. from django.contrib.auth import logout as auth_logout, login as auth_login
  9. from django.contrib.sites.models import get_current_site
  10. from django.conf import settings
  11. from oscar.core.loading import get_model
  12. from oscar.views.generic import PostActionMixin
  13. from oscar.apps.customer.utils import get_password_reset_url
  14. from oscar.core.loading import get_class, get_profile_class, get_classes
  15. from oscar.core.compat import get_user_model
  16. from . import signals
  17. PageTitleMixin, RegisterUserMixin = get_classes(
  18. 'customer.mixins', ['PageTitleMixin', 'RegisterUserMixin'])
  19. Dispatcher = get_class('customer.utils', 'Dispatcher')
  20. EmailAuthenticationForm, EmailUserCreationForm, OrderSearchForm = get_classes(
  21. 'customer.forms', ['EmailAuthenticationForm', 'EmailUserCreationForm',
  22. 'OrderSearchForm'])
  23. PasswordChangeForm = get_class('customer.forms', 'PasswordChangeForm')
  24. ProfileForm, ConfirmPasswordForm = get_classes(
  25. 'customer.forms', ['ProfileForm', 'ConfirmPasswordForm'])
  26. UserAddressForm = get_class('address.forms', 'UserAddressForm')
  27. Order = get_model('order', 'Order')
  28. Line = get_model('basket', 'Line')
  29. Basket = get_model('basket', 'Basket')
  30. UserAddress = get_model('address', 'UserAddress')
  31. Email = get_model('customer', 'Email')
  32. ProductAlert = get_model('customer', 'ProductAlert')
  33. CommunicationEventType = get_model('customer', 'CommunicationEventType')
  34. User = get_user_model()
  35. # =======
  36. # Account
  37. # =======
  38. class AccountSummaryView(generic.RedirectView):
  39. """
  40. View that exists for legacy reasons and customisability. It commonly gets
  41. called when the user clicks on "Account" in the navbar, and can be
  42. overridden to determine to what sub-page the user is directed without
  43. having to change a lot of templates.
  44. """
  45. url = reverse_lazy(settings.OSCAR_ACCOUNTS_REDIRECT_URL)
  46. class AccountRegistrationView(RegisterUserMixin, generic.FormView):
  47. form_class = EmailUserCreationForm
  48. template_name = 'customer/registration.html'
  49. redirect_field_name = 'next'
  50. def get(self, request, *args, **kwargs):
  51. if request.user.is_authenticated():
  52. return http.HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
  53. return super(AccountRegistrationView, self).get(
  54. request, *args, **kwargs)
  55. def get_logged_in_redirect(self):
  56. return reverse('customer:summary')
  57. def get_form_kwargs(self):
  58. kwargs = super(AccountRegistrationView, self).get_form_kwargs()
  59. kwargs['initial'] = {
  60. 'email': self.request.GET.get('email', ''),
  61. 'redirect_url': self.request.GET.get(self.redirect_field_name, '')
  62. }
  63. kwargs['host'] = self.request.get_host()
  64. return kwargs
  65. def get_context_data(self, *args, **kwargs):
  66. ctx = super(AccountRegistrationView, self).get_context_data(
  67. *args, **kwargs)
  68. ctx['cancel_url'] = self.request.META.get('HTTP_REFERER', None)
  69. return ctx
  70. def form_valid(self, form):
  71. self.register_user(form)
  72. return http.HttpResponseRedirect(
  73. form.cleaned_data['redirect_url'])
  74. class AccountAuthView(RegisterUserMixin, generic.TemplateView):
  75. """
  76. This is actually a slightly odd double form view that allows a customer to
  77. either login or register.
  78. """
  79. template_name = 'customer/login_registration.html'
  80. login_prefix, registration_prefix = 'login', 'registration'
  81. login_form_class = EmailAuthenticationForm
  82. registration_form_class = EmailUserCreationForm
  83. redirect_field_name = 'next'
  84. def get(self, request, *args, **kwargs):
  85. if request.user.is_authenticated():
  86. return http.HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
  87. return super(AccountAuthView, self).get(
  88. request, *args, **kwargs)
  89. def get_context_data(self, *args, **kwargs):
  90. ctx = super(AccountAuthView, self).get_context_data(*args, **kwargs)
  91. if 'login_form' not in kwargs:
  92. ctx['login_form'] = self.get_login_form()
  93. if 'registration_form' not in kwargs:
  94. ctx['registration_form'] = self.get_registration_form()
  95. return ctx
  96. def post(self, request, *args, **kwargs):
  97. # Use the name of the submit button to determine which form to validate
  98. if u'login_submit' in request.POST:
  99. return self.validate_login_form()
  100. elif u'registration_submit' in request.POST:
  101. return self.validate_registration_form()
  102. return http.HttpResponseBadRequest()
  103. # LOGIN
  104. def get_login_form(self, bind_data=False):
  105. return self.login_form_class(
  106. **self.get_login_form_kwargs(bind_data))
  107. def get_login_form_kwargs(self, bind_data=False):
  108. kwargs = {}
  109. kwargs['host'] = self.request.get_host()
  110. kwargs['prefix'] = self.login_prefix
  111. kwargs['initial'] = {
  112. 'redirect_url': self.request.GET.get(self.redirect_field_name, ''),
  113. }
  114. if bind_data and self.request.method in ('POST', 'PUT'):
  115. kwargs.update({
  116. 'data': self.request.POST,
  117. 'files': self.request.FILES,
  118. })
  119. return kwargs
  120. def validate_login_form(self):
  121. form = self.get_login_form(bind_data=True)
  122. if form.is_valid():
  123. user = form.get_user()
  124. # Grab a reference to the session ID before logging in
  125. old_session_key = self.request.session.session_key
  126. auth_login(self.request, form.get_user())
  127. # Raise signal robustly (we don't want exceptions to crash the
  128. # request handling). We use a custom signal as we want to track the
  129. # session key before calling login (which cycles the session ID).
  130. signals.user_logged_in.send_robust(
  131. sender=self, request=self.request, user=user,
  132. old_session_key=old_session_key)
  133. msg = self.get_login_success_message(form)
  134. messages.success(self.request, msg)
  135. url = self.get_login_success_url(form)
  136. return http.HttpResponseRedirect(url)
  137. ctx = self.get_context_data(login_form=form)
  138. return self.render_to_response(ctx)
  139. def get_login_success_message(self, form):
  140. return _("Welcome back")
  141. def get_login_success_url(self, form):
  142. redirect_url = form.cleaned_data['redirect_url']
  143. if redirect_url:
  144. return redirect_url
  145. # Redirect staff members to dashboard as that's the most likely place
  146. # they'll want to visit if they're logging in.
  147. if self.request.user.is_staff:
  148. return reverse('dashboard:index')
  149. return settings.LOGIN_REDIRECT_URL
  150. # REGISTRATION
  151. def get_registration_form(self, bind_data=False):
  152. return self.registration_form_class(
  153. **self.get_registration_form_kwargs(bind_data))
  154. def get_registration_form_kwargs(self, bind_data=False):
  155. kwargs = {}
  156. kwargs['host'] = self.request.get_host()
  157. kwargs['prefix'] = self.registration_prefix
  158. kwargs['initial'] = {
  159. 'redirect_url': self.request.GET.get(self.redirect_field_name, ''),
  160. }
  161. if bind_data and self.request.method in ('POST', 'PUT'):
  162. kwargs.update({
  163. 'data': self.request.POST,
  164. 'files': self.request.FILES,
  165. })
  166. return kwargs
  167. def validate_registration_form(self):
  168. form = self.get_registration_form(bind_data=True)
  169. if form.is_valid():
  170. self.register_user(form)
  171. msg = self.get_registration_success_message(form)
  172. messages.success(self.request, msg)
  173. url = self.get_registration_success_url(form)
  174. return http.HttpResponseRedirect(url)
  175. ctx = self.get_context_data(registration_form=form)
  176. return self.render_to_response(ctx)
  177. def get_registration_success_message(self, form):
  178. return _("Thanks for registering!")
  179. def get_registration_success_url(self, form):
  180. return settings.LOGIN_REDIRECT_URL
  181. class LogoutView(generic.RedirectView):
  182. url = settings.OSCAR_HOMEPAGE
  183. permanent = False
  184. def get(self, request, *args, **kwargs):
  185. auth_logout(request)
  186. response = super(LogoutView, self).get(request, *args, **kwargs)
  187. for cookie in settings.OSCAR_COOKIES_DELETE_ON_LOGOUT:
  188. response.delete_cookie(cookie)
  189. return response
  190. # =============
  191. # Profile
  192. # =============
  193. class ProfileView(PageTitleMixin, generic.TemplateView):
  194. template_name = 'customer/profile/profile.html'
  195. page_title = _('Profile')
  196. active_tab = 'profile'
  197. def get_context_data(self, **kwargs):
  198. ctx = super(ProfileView, self).get_context_data(**kwargs)
  199. ctx['profile_fields'] = self.get_profile_fields(self.request.user)
  200. return ctx
  201. def get_profile_fields(self, user):
  202. field_data = []
  203. # Check for custom user model
  204. for field_name in User._meta.additional_fields:
  205. field_data.append(
  206. self.get_model_field_data(user, field_name))
  207. # Check for profile class
  208. profile_class = get_profile_class()
  209. if profile_class:
  210. try:
  211. profile = profile_class.objects.get(user=user)
  212. except ObjectDoesNotExist:
  213. profile = profile_class(user=user)
  214. field_names = [f.name for f in profile._meta.local_fields]
  215. for field_name in field_names:
  216. if field_name in ('user', 'id'):
  217. continue
  218. field_data.append(
  219. self.get_model_field_data(profile, field_name))
  220. return field_data
  221. def get_model_field_data(self, model_class, field_name):
  222. """
  223. Extract the verbose name and value for a model's field value
  224. """
  225. field = model_class._meta.get_field(field_name)
  226. if field.choices:
  227. value = getattr(model_class, 'get_%s_display' % field_name)()
  228. else:
  229. value = getattr(model_class, field_name)
  230. return {
  231. 'name': getattr(field, 'verbose_name'),
  232. 'value': value,
  233. }
  234. class ProfileUpdateView(PageTitleMixin, generic.FormView):
  235. form_class = ProfileForm
  236. template_name = 'customer/profile/profile_form.html'
  237. communication_type_code = 'EMAIL_CHANGED'
  238. page_title = _('Edit Profile')
  239. active_tab = 'profile'
  240. success_url = reverse_lazy('customer:profile-view')
  241. def get_form_kwargs(self):
  242. kwargs = super(ProfileUpdateView, self).get_form_kwargs()
  243. kwargs['user'] = self.request.user
  244. return kwargs
  245. def form_valid(self, form):
  246. # Grab current user instance before we save form. We may need this to
  247. # send a warning email if the email address is changed.
  248. try:
  249. old_user = User.objects.get(id=self.request.user.id)
  250. except User.DoesNotExist:
  251. old_user = None
  252. form.save()
  253. # We have to look up the email address from the form's
  254. # cleaned data because the object created by form.save() can
  255. # either be a user or profile instance depending whether a profile
  256. # class has been specified by the AUTH_PROFILE_MODULE setting.
  257. new_email = form.cleaned_data['email']
  258. if old_user and new_email != old_user.email:
  259. # Email address has changed - send a confirmation email to the old
  260. # address including a password reset link in case this is a
  261. # suspicious change.
  262. ctx = {
  263. 'user': self.request.user,
  264. 'site': get_current_site(self.request),
  265. 'reset_url': get_password_reset_url(old_user),
  266. 'new_email': new_email,
  267. }
  268. msgs = CommunicationEventType.objects.get_and_render(
  269. code=self.communication_type_code, context=ctx)
  270. Dispatcher().dispatch_user_messages(old_user, msgs)
  271. messages.success(self.request, _("Profile updated"))
  272. return redirect(self.get_success_url())
  273. class ProfileDeleteView(PageTitleMixin, generic.FormView):
  274. form_class = ConfirmPasswordForm
  275. template_name = 'customer/profile/profile_delete.html'
  276. page_title = _('Delete profile')
  277. active_tab = 'profile'
  278. success_url = settings.OSCAR_HOMEPAGE
  279. def get_form_kwargs(self):
  280. kwargs = super(ProfileDeleteView, self).get_form_kwargs()
  281. kwargs['user'] = self.request.user
  282. return kwargs
  283. def form_valid(self, form):
  284. self.request.user.delete()
  285. messages.success(
  286. self.request,
  287. _("Your profile has now been deleted. Thanks for using the site."))
  288. return http.HttpResponseRedirect(self.get_success_url())
  289. class ChangePasswordView(PageTitleMixin, generic.FormView):
  290. form_class = PasswordChangeForm
  291. template_name = 'customer/profile/change_password_form.html'
  292. communication_type_code = 'PASSWORD_CHANGED'
  293. page_title = _('Change Password')
  294. active_tab = 'profile'
  295. success_url = reverse_lazy('customer:profile-view')
  296. def get_form_kwargs(self):
  297. kwargs = super(ChangePasswordView, self).get_form_kwargs()
  298. kwargs['user'] = self.request.user
  299. return kwargs
  300. def form_valid(self, form):
  301. form.save()
  302. messages.success(self.request, _("Password updated"))
  303. ctx = {
  304. 'user': self.request.user,
  305. 'site': get_current_site(self.request),
  306. 'reset_url': get_password_reset_url(self.request.user),
  307. }
  308. msgs = CommunicationEventType.objects.get_and_render(
  309. code=self.communication_type_code, context=ctx)
  310. Dispatcher().dispatch_user_messages(self.request.user, msgs)
  311. return redirect(self.get_success_url())
  312. # =============
  313. # Email history
  314. # =============
  315. class EmailHistoryView(PageTitleMixin, generic.ListView):
  316. context_object_name = "emails"
  317. template_name = 'customer/email/email_list.html'
  318. paginate_by = 20
  319. page_title = _('Email History')
  320. active_tab = 'emails'
  321. def get_queryset(self):
  322. return Email._default_manager.filter(user=self.request.user)
  323. class EmailDetailView(PageTitleMixin, generic.DetailView):
  324. """Customer email"""
  325. template_name = "customer/email/email_detail.html"
  326. context_object_name = 'email'
  327. active_tab = 'emails'
  328. def get_object(self, queryset=None):
  329. return get_object_or_404(Email, user=self.request.user,
  330. id=self.kwargs['email_id'])
  331. def get_page_title(self):
  332. """Append email subject to page title"""
  333. return u'%s: %s' % (_('Email'), self.object.subject)
  334. # =============
  335. # Order history
  336. # =============
  337. class OrderHistoryView(PageTitleMixin, generic.ListView):
  338. """
  339. Customer order history
  340. """
  341. context_object_name = "orders"
  342. template_name = 'customer/order/order_list.html'
  343. paginate_by = 20
  344. model = Order
  345. form_class = OrderSearchForm
  346. page_title = _('Order History')
  347. active_tab = 'orders'
  348. def get(self, request, *args, **kwargs):
  349. if 'date_from' in request.GET:
  350. self.form = self.form_class(self.request.GET)
  351. if not self.form.is_valid():
  352. self.object_list = self.get_queryset()
  353. ctx = self.get_context_data(object_list=self.object_list)
  354. return self.render_to_response(ctx)
  355. data = self.form.cleaned_data
  356. # If the user has just entered an order number, try and look it up
  357. # and redirect immediately to the order detail page.
  358. if data['order_number'] and not (data['date_to'] or
  359. data['date_from']):
  360. try:
  361. order = Order.objects.get(
  362. number=data['order_number'], user=self.request.user)
  363. except Order.DoesNotExist:
  364. pass
  365. else:
  366. return http.HttpResponseRedirect(
  367. reverse('customer:order',
  368. kwargs={'order_number': order.number}))
  369. else:
  370. self.form = self.form_class()
  371. return super(OrderHistoryView, self).get(request, *args, **kwargs)
  372. def get_queryset(self):
  373. qs = self.model._default_manager.filter(user=self.request.user)
  374. if self.form.is_bound and self.form.is_valid():
  375. qs = qs.filter(**self.form.get_filters())
  376. return qs
  377. def get_context_data(self, *args, **kwargs):
  378. ctx = super(OrderHistoryView, self).get_context_data(*args, **kwargs)
  379. ctx['form'] = self.form
  380. return ctx
  381. class OrderDetailView(PageTitleMixin, PostActionMixin, generic.DetailView):
  382. model = Order
  383. active_tab = 'orders'
  384. def get_template_names(self):
  385. return ["customer/order/order_detail.html"]
  386. def get_page_title(self):
  387. """
  388. Order number as page title
  389. """
  390. return u'%s #%s' % (_('Order'), self.object.number)
  391. def get_object(self, queryset=None):
  392. return get_object_or_404(self.model, user=self.request.user,
  393. number=self.kwargs['order_number'])
  394. def do_reorder(self, order): # noqa (too complex (10))
  395. """
  396. 'Re-order' a previous order.
  397. This puts the contents of the previous order into your basket
  398. """
  399. # Collect lines to be added to the basket and any warnings for lines
  400. # that are no longer available.
  401. basket = self.request.basket
  402. lines_to_add = []
  403. warnings = []
  404. for line in order.lines.all():
  405. is_available, reason = line.is_available_to_reorder(
  406. basket, self.request.strategy)
  407. if is_available:
  408. lines_to_add.append(line)
  409. else:
  410. warnings.append(reason)
  411. # Check whether the number of items in the basket won't exceed the
  412. # maximum.
  413. total_quantity = sum([line.quantity for line in lines_to_add])
  414. is_quantity_allowed, reason = basket.is_quantity_allowed(
  415. total_quantity)
  416. if not is_quantity_allowed:
  417. messages.warning(self.request, reason)
  418. self.response = redirect('customer:order-list')
  419. return
  420. # Add any warnings
  421. for warning in warnings:
  422. messages.warning(self.request, warning)
  423. for line in lines_to_add:
  424. options = []
  425. for attribute in line.attributes.all():
  426. if attribute.option:
  427. options.append({
  428. 'option': attribute.option,
  429. 'value': attribute.value})
  430. basket.add_product(line.product, line.quantity, options)
  431. if len(lines_to_add) > 0:
  432. self.response = redirect('basket:summary')
  433. messages.info(
  434. self.request,
  435. _("All available lines from order %(number)s "
  436. "have been added to your basket") % {'number': order.number})
  437. else:
  438. self.response = redirect('customer:order-list')
  439. messages.warning(
  440. self.request,
  441. _("It is not possible to re-order order %(number)s "
  442. "as none of its lines are available to purchase") %
  443. {'number': order.number})
  444. class OrderLineView(PostActionMixin, generic.DetailView):
  445. """Customer order line"""
  446. def get_object(self, queryset=None):
  447. order = get_object_or_404(Order, user=self.request.user,
  448. number=self.kwargs['order_number'])
  449. return order.lines.get(id=self.kwargs['line_id'])
  450. def do_reorder(self, line):
  451. self.response = http.HttpResponseRedirect(
  452. reverse('customer:order',
  453. args=(int(self.kwargs['order_number']),)))
  454. basket = self.request.basket
  455. line_available_to_reorder, reason = line.is_available_to_reorder(
  456. basket, self.request.strategy)
  457. if not line_available_to_reorder:
  458. messages.warning(self.request, reason)
  459. return
  460. # We need to pass response to the get_or_create... method
  461. # as a new basket might need to be created
  462. self.response = http.HttpResponseRedirect(reverse('basket:summary'))
  463. # Convert line attributes into basket options
  464. options = []
  465. for attribute in line.attributes.all():
  466. if attribute.option:
  467. options.append({'option': attribute.option,
  468. 'value': attribute.value})
  469. basket.add_product(line.product, line.quantity, options)
  470. if line.quantity > 1:
  471. msg = _("%(qty)d copies of '%(product)s' have been added to your"
  472. " basket") % {
  473. 'qty': line.quantity, 'product': line.product}
  474. else:
  475. msg = _("'%s' has been added to your basket") % line.product
  476. messages.info(self.request, msg)
  477. class AnonymousOrderDetailView(generic.DetailView):
  478. model = Order
  479. template_name = "customer/anon_order.html"
  480. def get_object(self, queryset=None):
  481. # Check URL hash matches that for order to prevent spoof attacks
  482. order = get_object_or_404(self.model, user=None,
  483. number=self.kwargs['order_number'])
  484. if self.kwargs['hash'] != order.verification_hash():
  485. raise http.Http404()
  486. return order
  487. # ------------
  488. # Address book
  489. # ------------
  490. class AddressListView(PageTitleMixin, generic.ListView):
  491. """Customer address book"""
  492. context_object_name = "addresses"
  493. template_name = 'customer/address/address_list.html'
  494. paginate_by = 40
  495. active_tab = 'addresses'
  496. page_title = _('Address Book')
  497. def get_queryset(self):
  498. """Return customer's addresses"""
  499. return UserAddress._default_manager.filter(user=self.request.user)
  500. class AddressCreateView(PageTitleMixin, generic.CreateView):
  501. form_class = UserAddressForm
  502. model = UserAddress
  503. template_name = 'customer/address/address_form.html'
  504. active_tab = 'addresses'
  505. page_title = _('Add a new address')
  506. success_url = reverse_lazy('customer:address-list')
  507. def get_form_kwargs(self):
  508. kwargs = super(AddressCreateView, self).get_form_kwargs()
  509. kwargs['user'] = self.request.user
  510. return kwargs
  511. def get_context_data(self, **kwargs):
  512. ctx = super(AddressCreateView, self).get_context_data(**kwargs)
  513. ctx['title'] = _('Add a new address')
  514. return ctx
  515. def get_success_url(self):
  516. messages.success(self.request,
  517. _("Address '%s' created") % self.object.summary)
  518. return super(AddressCreateView, self).get_success_url()
  519. class AddressUpdateView(PageTitleMixin, generic.UpdateView):
  520. form_class = UserAddressForm
  521. model = UserAddress
  522. template_name = 'customer/address/address_form.html'
  523. active_tab = 'addresses'
  524. page_title = _('Edit address')
  525. success_url = reverse_lazy('customer:address-list')
  526. def get_form_kwargs(self):
  527. kwargs = super(AddressUpdateView, self).get_form_kwargs()
  528. kwargs['user'] = self.request.user
  529. return kwargs
  530. def get_context_data(self, **kwargs):
  531. ctx = super(AddressUpdateView, self).get_context_data(**kwargs)
  532. ctx['title'] = _('Edit address')
  533. return ctx
  534. def get_queryset(self):
  535. return self.request.user.addresses.all()
  536. def get_success_url(self):
  537. messages.success(self.request,
  538. _("Address '%s' updated") % self.object.summary)
  539. return super(AddressUpdateView, self).get_success_url()
  540. class AddressDeleteView(PageTitleMixin, generic.DeleteView):
  541. model = UserAddress
  542. template_name = "customer/address/address_delete.html"
  543. page_title = _('Delete address?')
  544. active_tab = 'addresses'
  545. context_object_name = 'address'
  546. success_url = reverse_lazy('customer:address-list')
  547. def get_queryset(self):
  548. return UserAddress._default_manager.filter(user=self.request.user)
  549. def get_success_url(self):
  550. messages.success(self.request,
  551. _("Address '%s' deleted") % self.object.summary)
  552. return super(AddressDeleteView, self).get_success_url()
  553. class AddressChangeStatusView(generic.RedirectView):
  554. """
  555. Sets an address as default_for_(billing|shipping)
  556. """
  557. url = reverse_lazy('customer:address-list')
  558. permanent = False
  559. def get(self, request, pk=None, action=None, *args, **kwargs):
  560. address = get_object_or_404(UserAddress, user=self.request.user,
  561. pk=pk)
  562. # We don't want the user to set an address as the default shipping
  563. # address, though they should be able to set it as their billing
  564. # address.
  565. if address.country.is_shipping_country:
  566. setattr(address, 'is_%s' % action, True)
  567. elif action == 'default_for_billing':
  568. setattr(address, 'is_default_for_billing', True)
  569. else:
  570. messages.error(request, _('We do not ship to this country'))
  571. address.save()
  572. return super(AddressChangeStatusView, self).get(
  573. request, *args, **kwargs)