Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

views.py 25KB

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