views.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. from django.shortcuts import render, get_object_or_404, redirect
  2. from django.http import HttpResponse, Http404
  3. from django.template import TemplateDoesNotExist
  4. from django.template.loader import get_template
  5. from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView
  6. from django.contrib.auth.decorators import login_required
  7. from django.contrib.auth.mixins import LoginRequiredMixin
  8. from django.contrib.auth import logout
  9. from django.contrib import messages
  10. from django.contrib.messages.views import SuccessMessageMixin
  11. from django.views.generic.edit import UpdateView, CreateView, DeleteView
  12. from django.views.generic.base import TemplateView
  13. from django.urls import reverse_lazy
  14. from django.core.signing import BadSignature
  15. from django.core.paginator import Paginator
  16. from django.db.models import Q
  17. from .models import AdvUser, SubRubric, Ad, Comment
  18. from .forms import ChangeUserInfoForm, RegisterUserForm, SearchForm, AdForm, AIFormSet, UserCommentForm, GuestCommentForm
  19. from .utilities import signer
  20. def index(request):
  21. # Вывод последних 10 объявлений
  22. ads = Ad.objects.filter(is_active=True)[:10]
  23. context = {'ads': ads}
  24. return render(request, 'main/index.html', context)
  25. def other_page(request, page):
  26. try:
  27. template = get_template('main/' + page + '.html')
  28. except TemplateDoesNotExist:
  29. raise Http404
  30. return HttpResponse(template.render(request=request))
  31. class BLoginView(LoginView):
  32. template_name = 'main/login.html'
  33. @login_required
  34. def profile(request):
  35. ads = Ad.objects.filter(author=request.user.pk)
  36. context = {'ads': ads}
  37. return render(request, 'main/profile.html', context)
  38. class BLogoutView(LoginRequiredMixin, LogoutView):
  39. template_name = 'main/logout.html'
  40. class ChangeUserInfoView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
  41. model = AdvUser
  42. template_name = 'main/change_user_info.html'
  43. form_class = ChangeUserInfoForm
  44. success_url = reverse_lazy('main:profile')
  45. success_message = 'Данные пользователя изменены'
  46. def setup(self, request, *args, **kwargs):
  47. self.user_id = request.user.pk
  48. return super().setup(request, *args, **kwargs)
  49. def get_object(self, queryset=None):
  50. if not queryset:
  51. queryset = self.get_queryset()
  52. return get_object_or_404(queryset, pk=self.user_id)
  53. class BPasswordChangeView(SuccessMessageMixin, LoginRequiredMixin, PasswordChangeView):
  54. template_name = 'main/password_change.html'
  55. success_url = reverse_lazy('main:profile')
  56. success_message = 'Пароль пользователя изменен'
  57. class RegisterUserView(CreateView):
  58. model = AdvUser
  59. template_name = 'main/register_user.html'
  60. form_class = RegisterUserForm
  61. success_url = reverse_lazy('main:register_done')
  62. class RegisterDoneView(TemplateView):
  63. template_name = 'main/register_done.html'
  64. def user_activate(request, sign):
  65. try:
  66. username = signer.unsign(sign)
  67. except BadSignature:
  68. return render(request, 'main/bad_signature.html')
  69. user = get_object_or_404(AdvUser, username=username)
  70. if user.is_activated:
  71. template = 'main/user_is_activated.html'
  72. else:
  73. template = 'main/activation_done.html'
  74. user.is_active = True
  75. user.is_activated = True
  76. user.save()
  77. return render(request, template)
  78. class DeleteUserView(LoginRequiredMixin, DeleteView):
  79. model = AdvUser
  80. template_name = 'main/delete_user.html'
  81. success_url = reverse_lazy('main:index')
  82. def setup(self, request, *args, **kwargs): # Сохраняем ключ текущего пользователя
  83. self.user_id = request.user.pk
  84. return super().setup(request, *args, **kwargs)
  85. def post(self, request, *args, **kwargs): # Делаем выход для текущего пользователя и создаем всплывающее сообщение об успешном удалении
  86. logout(request)
  87. messages.add_message(request, messages.SUCCESS, 'Пользователь удален')
  88. return super().post(request, *args, **kwargs)
  89. def get_object(self, queryset=None): # Отыскиваем по ключу пользователя, подлежащего удалению
  90. if not queryset:
  91. queryset = self.get_queryset()
  92. return get_object_or_404(queryset, pk=self.user_id)
  93. def by_rubric(request, pk):
  94. rubric = get_object_or_404(SubRubric, pk=pk) # Название рубрики
  95. ads = Ad.objects.filter(is_active=True, rubric=pk) # Объявления, относящиеся к рубрике
  96. keyword = request.GET.get('keyword', False)
  97. if keyword:
  98. q = Q(title__icontains=keyword) | Q(content__icontains=keyword) # Фильтрация уже отобранных объявлений по введенному пользователю искомому слову
  99. ads = ads.filter(q)
  100. else:
  101. keyword = ''
  102. form = SearchForm(initial={'keyword': keyword}) # Вывод формы поиска
  103. paginator = Paginator(ads, 2) # Пагинатор, выводящий по 2 объявления
  104. page = request.GET.get('page', False)
  105. if page:
  106. page_num = page
  107. else:
  108. page_num = 1
  109. page = paginator.get_page(page_num)
  110. context = {'rubric': rubric, 'page': page, 'ads': page.object_list, 'form': form}
  111. return render(request, 'main/by_rubric.html', context)
  112. def detail(request, rubric_pk, pk):
  113. ad = Ad.objects.get(pk=pk)
  114. ais = ad.additionalimage_set.all()
  115. comments = Comment.objects.filter(ad=pk, is_active=True)
  116. initial = {'ad': ad.pk} # В поле ad создаваемой формы ввода комментария заносим ключ выводящегося на странице объявления. С этим объявлением будет связан комментарий.
  117. if request.user.is_authenticated:
  118. initial['author'] = request.user.username
  119. form_class = UserCommentForm
  120. else:
  121. form_class = GuestCommentForm
  122. form = form_class(initial=initial)
  123. if request.method == 'POST':
  124. c_form = form_class(request.POST)
  125. if c_form.is_valid():
  126. c_form.save()
  127. messages.add_message(request, messages.SUCCESS, 'Комментарий добавлен')
  128. else:
  129. form = c_form # Переносим форму из переменной c_form в переменную form. Эта форма, хранящая некорректные данные и сообщения об ошибках ввода, будет выведена на экран,
  130. # и посетитель сразу увидит, что он ввел не так.
  131. messages.add_message(request, messages.WARNING, 'Комментарий не добавлен')
  132. context = {'ad': ad, 'ais': ais, 'comments': comments, 'form': form}
  133. return render(request, 'main/detail.html', context)
  134. @login_required
  135. def profile_ad_detail(request, pk):
  136. ad = get_object_or_404(Ad, pk=pk)
  137. ais = ad.additionalimage_set.all()
  138. comments = Comment.objects.filter(ad=pk, is_active=True)
  139. context = {'ad': ad, 'ais': ais, 'comments': comments}
  140. return render(request, 'main/profile_ad_detail.html', context)
  141. @login_required
  142. def profile_ad_add(request):
  143. if request.method == 'POST':
  144. form = AdForm(request.POST, request.FILES)
  145. if form.is_valid():
  146. ad = form.save()
  147. formset = AIFormSet(request.POST, request.FILES, instance=ad)
  148. if formset.is_valid():
  149. formset.save()
  150. messages.add_message(request, messages.SUCCESS, 'Объявление добавлено')
  151. return redirect('main:profile')
  152. else:
  153. form = AdForm(initial={'author': request.user.pk})
  154. formset = AIFormSet()
  155. context = {'form': form, 'formset': formset}
  156. return render(request, 'main/profile_ad_add.html', context)
  157. @login_required
  158. def profile_ad_change(request, pk):
  159. ad = get_object_or_404(Ad, pk=pk)
  160. if request.method == 'POST':
  161. form = AdForm(request.POST, request.FILES, instance=ad)
  162. if form.is_valid():
  163. ad = form.save()
  164. formset = AIFormSet(request.POST, request.FILES, instance=ad)
  165. if formset.is_valid():
  166. formset.save()
  167. messages.add_message(request, messages.SUCCESS, 'Объявление исправлено')
  168. return redirect('main:profile')
  169. else:
  170. form = AdForm(instance=ad)
  171. formset = AIFormSet(instance=ad)
  172. context = {'form': form, 'formset': formset}
  173. return render(request, 'main/profile_ad_change.html', context)
  174. @login_required
  175. def profile_ad_delete(request, pk):
  176. ad = get_object_or_404(Ad, pk=pk)
  177. if request.method == 'POST':
  178. ad.delete()
  179. messages.add_message(request, messages.SUCCESS, 'Объявление удалено')
  180. return redirect('main:profile')
  181. else:
  182. context = {'ad': ad}
  183. return render(request, 'main/profile_ad_delete.html', context)