Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. from django.db.models import Q
  2. from django.contrib import messages
  3. from django.shortcuts import redirect
  4. from django.utils.translation import ugettext_lazy as _
  5. from django.core.urlresolvers import reverse
  6. from django.views.generic import ListView, DetailView, DeleteView, \
  7. UpdateView, FormView, TemplateView
  8. from django.views.generic.detail import SingleObjectMixin
  9. from django.views.generic.edit import FormMixin
  10. from django_tables2 import SingleTableMixin
  11. from oscar.apps.customer.utils import normalise_email
  12. from oscar.views.generic import BulkEditMixin
  13. from oscar.core.compat import get_user_model
  14. from oscar.core.loading import get_class, get_classes, get_model
  15. UserSearchForm, ProductAlertSearchForm, ProductAlertUpdateForm = get_classes(
  16. 'dashboard.users.forms', ('UserSearchForm', 'ProductAlertSearchForm',
  17. 'ProductAlertUpdateForm'))
  18. PasswordResetForm = get_class('customer.forms', 'PasswordResetForm')
  19. UserTable = get_class('dashboard.users.tables', 'UserTable')
  20. ProductAlert = get_model('customer', 'ProductAlert')
  21. User = get_user_model()
  22. class IndexView(BulkEditMixin, SingleTableMixin, FormMixin, TemplateView):
  23. template_name = 'dashboard/users/index.html'
  24. table_pagination = True
  25. model = User
  26. actions = ('make_active', 'make_inactive', )
  27. form_class = UserSearchForm
  28. table_class = UserTable
  29. context_table_name = 'users'
  30. desc_template = _('%(main_filter)s %(email_filter)s %(name_filter)s')
  31. description = ''
  32. def dispatch(self, request, *args, **kwargs):
  33. form_class = self.get_form_class()
  34. self.form = self.get_form(form_class)
  35. return super(IndexView, self).dispatch(request, *args, **kwargs)
  36. def get_form_kwargs(self):
  37. """
  38. Only bind search form if it was submitted.
  39. """
  40. kwargs = super(IndexView, self).get_form_kwargs()
  41. if 'search' in self.request.GET:
  42. kwargs.update({
  43. 'data': self.request.GET,
  44. })
  45. return kwargs
  46. def get_queryset(self):
  47. queryset = self.model.objects.all().order_by('-date_joined')
  48. return self.apply_search(queryset)
  49. def apply_search(self, queryset):
  50. # Set initial queryset description, used for template context
  51. self.desc_ctx = {
  52. 'main_filter': _('All users'),
  53. 'email_filter': '',
  54. 'name_filter': '',
  55. }
  56. if self.form.is_valid():
  57. return self.apply_search_filters(queryset, self.form.cleaned_data)
  58. else:
  59. return queryset
  60. def apply_search_filters(self, queryset, data):
  61. """
  62. Function is split out to allow customisation with little boilerplate.
  63. """
  64. if data['email']:
  65. email = normalise_email(data['email'])
  66. queryset = queryset.filter(email__istartswith=email)
  67. self.desc_ctx['email_filter'] \
  68. = _(" with email matching '%s'") % email
  69. if data['name']:
  70. # If the value is two words, then assume they are first name and
  71. # last name
  72. parts = data['name'].split()
  73. if len(parts) == 2:
  74. condition = Q(first_name__istartswith=parts[0]) \
  75. | Q(last_name__istartswith=parts[1])
  76. else:
  77. condition = Q(first_name__istartswith=data['name']) \
  78. | Q(last_name__istartswith=data['name'])
  79. queryset = queryset.filter(condition).distinct()
  80. self.desc_ctx['name_filter'] \
  81. = _(" with name matching '%s'") % data['name']
  82. return queryset
  83. def get_context_data(self, **kwargs):
  84. context = super(IndexView, self).get_context_data(**kwargs)
  85. context['form'] = self.form
  86. context['queryset_description'] = self.desc_template % self.desc_ctx
  87. context['queryset_icon'] = 'group'
  88. return context
  89. def make_inactive(self, request, users):
  90. return self._change_users_active_status(users, False)
  91. def make_active(self, request, users):
  92. return self._change_users_active_status(users, True)
  93. def _change_users_active_status(self, users, value):
  94. for user in users:
  95. if not user.is_superuser:
  96. user.is_active = value
  97. user.save()
  98. messages.info(self.request, _("Users' status successfully changed"))
  99. return redirect('dashboard:users-index')
  100. class UserDetailView(DetailView):
  101. template_name = 'dashboard/users/detail.html'
  102. model = User
  103. context_object_name = 'customer'
  104. class PasswordResetView(SingleObjectMixin, FormView):
  105. form_class = PasswordResetForm
  106. http_method_names = ['post']
  107. model = User
  108. def post(self, request, *args, **kwargs):
  109. self.object = self.get_object()
  110. return super(PasswordResetView, self).post(request, *args, **kwargs)
  111. def get_form_kwargs(self):
  112. kwargs = super(PasswordResetView, self).get_form_kwargs()
  113. kwargs['data'] = {'email': self.object.email}
  114. return kwargs
  115. def form_valid(self, form):
  116. # The PasswordResetForm's save method sends the reset email
  117. form.save(request=self.request)
  118. return super(PasswordResetView, self).form_valid(form)
  119. def get_success_url(self):
  120. messages.success(
  121. self.request, _("A password reset email has been sent"))
  122. return reverse(
  123. 'dashboard:user-detail', kwargs={'pk': self.object.id}
  124. )
  125. class ProductAlertListView(ListView):
  126. model = ProductAlert
  127. form_class = ProductAlertSearchForm
  128. context_object_name = 'alerts'
  129. template_name = 'dashboard/users/alerts/list.html'
  130. paginate_by = 20
  131. base_description = _('All Alerts')
  132. description = ''
  133. def get_queryset(self):
  134. queryset = self.model.objects.all()
  135. self.description = self.base_description
  136. self.form = self.form_class(self.request.GET)
  137. if not self.form.is_valid():
  138. return queryset
  139. data = self.form.cleaned_data
  140. if data['status']:
  141. queryset = queryset.filter(status=data['status']).distinct()
  142. self.description \
  143. += _(" with status matching '%s'") % data['status']
  144. if data['name']:
  145. # If the value is two words, then assume they are first name and
  146. # last name
  147. parts = data['name'].split()
  148. if len(parts) >= 2:
  149. queryset = queryset.filter(
  150. user__first_name__istartswith=parts[0],
  151. user__last_name__istartswith=parts[1]
  152. ).distinct()
  153. else:
  154. queryset = queryset.filter(
  155. Q(user__first_name__istartswith=parts[0]) |
  156. Q(user__last_name__istartswith=parts[-1])
  157. ).distinct()
  158. self.description \
  159. += _(" with customer name matching '%s'") % data['name']
  160. if data['email']:
  161. queryset = queryset.filter(
  162. Q(user__email__icontains=data['email']) |
  163. Q(email__icontains=data['email'])
  164. )
  165. self.description \
  166. += _(" with customer email matching '%s'") % data['email']
  167. return queryset
  168. def get_context_data(self, **kwargs):
  169. context = super(ProductAlertListView, self).get_context_data(**kwargs)
  170. context['form'] = self.form
  171. context['queryset_description'] = self.description
  172. return context
  173. class ProductAlertUpdateView(UpdateView):
  174. template_name = 'dashboard/users/alerts/update.html'
  175. model = ProductAlert
  176. form_class = ProductAlertUpdateForm
  177. context_object_name = 'alert'
  178. def get_success_url(self):
  179. messages.success(self.request, _("Product alert saved"))
  180. return reverse('dashboard:user-alert-list')
  181. class ProductAlertDeleteView(DeleteView):
  182. model = ProductAlert
  183. template_name = 'dashboard/users/alerts/delete.html'
  184. context_object_name = 'alert'
  185. def get_success_url(self):
  186. messages.warning(self.request, _("Product alert deleted"))
  187. return reverse('dashboard:user-alert-list')