1
from datetime import datetime
3
from django.contrib.auth.decorators import login_required, user_passes_test
4
from django.core.files import File
5
from django.http import Http404, HttpResponseRedirect
6
from django.shortcuts import render, redirect
7
from django.urls import reverse
8
from django.utils.decorators import method_decorator
9
from django.views import View
10
from elasticsearch import exceptions as es_exceptions
12
from books.es_index import BookIndex
13
from books.forms import BookCreateFrom, SearchForm, CommentForm
14
from books.models import Comment, BookStatistic
15
from elasticsearch_control.decorators import elasticsearch_check_available
18
@method_decorator(login_required, name="dispatch")
19
@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch")
20
@method_decorator(elasticsearch_check_available, name="dispatch")
21
class CreateBookView(View):
26
def get(self, request):
31
"form": BookCreateFrom(),
33
"page_name": "book-create",
37
def post(self, request):
38
# Создаем новую запись
39
book_form = BookCreateFrom(request.POST)
40
# Проверяем, действительна ли форма и загружен ли файл.
41
if book_form.is_valid() and request.FILES.get("book_file"):
42
book = BookIndex.create(
43
title=book_form.cleaned_data["title"],
44
author=book_form.cleaned_data["author"],
45
year=str(book_form.cleaned_data["year"] or ""),
46
about=book_form.cleaned_data["about"],
49
# Проверка успешности создания книги.
51
file: File = request.FILES["book_file"]
52
book.set_file(file.name, file)
53
return redirect(reverse("book-about", args=[book.id]))
61
"page_name": "book-create",
66
@method_decorator(login_required, name="dispatch")
67
@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch")
68
@method_decorator(elasticsearch_check_available, name="dispatch")
69
class UpdateBookView(View):
71
Обновляет книгу с заданным book_id данными из запроса.
74
def get(self, request, book_id: str):
75
book = BookIndex.get(book_id)
83
"form": BookCreateFrom(book.json()),
85
"page_name": "book-edit",
89
def post(self, request, book_id: str):
90
# Создаем новую запись
91
book_form = BookCreateFrom(request.POST)
92
# Проверка правильности формы.
93
if book_form.is_valid():
94
book = BookIndex.get(book_id, values=["title"])
98
book.title = book_form.cleaned_data["title"]
99
book.author = book_form.cleaned_data["author"]
100
book.year = str(book_form.cleaned_data["year"])
101
book.about = book_form.cleaned_data["about"]
102
book.published_at = datetime.now()
105
return redirect(reverse("book-about", args=[book.id]))
113
"page_name": "book-edit",
118
@method_decorator(login_required, name="dispatch")
119
@method_decorator(user_passes_test(lambda u: u.is_superuser), name="dispatch")
120
@method_decorator(elasticsearch_check_available, name="dispatch")
121
class DeleteBookView(View):
123
Удаляет книгу с идентификатором book_id.
126
def post(self, request, book_id: str):
127
book = BookIndex.get(book_id, values=["title"])
134
return redirect("books-list")
138
@elasticsearch_check_available
139
def show(request, book_id):
141
Возвращает файл книги
144
book = BookIndex.get(book_id, values=["title"])
145
if book and book.get_file():
146
return redirect(f"/media/books/{book.id}/{book.get_file().name}")
151
@elasticsearch_check_available
152
def about_book(request, book_id):
154
Возвращает описание книги
157
# Получаем запись по ID
158
book = BookIndex.get(id_=book_id)
159
comments = Comment.objects.filter(book_id=book_id).select_related("user")
160
book_stats, _ = BookStatistic.objects.get_or_create(
161
book_id=book_id, user=request.user
166
"books/about_book.html",
169
"statistic": book_stats,
170
"comments": comments,
173
# Перехват исключения, которое выдается, когда книга не найдена.
174
except es_exceptions.NotFoundError:
179
@elasticsearch_check_available
180
def all_books(request):
185
# Создание нового экземпляра класса SearchForm и передача данных request.GET.
186
search_form = SearchForm(request.GET)
187
# Проверка корректности запроса и корректности формы поиска.
188
if not search_form.is_valid():
189
return HttpResponseRedirect(reverse("books-list"))
191
# Ищем по полям, переданным в запросе
192
paginator = BookIndex.filter(
193
search=search_form.cleaned_data["search_text"],
194
year=search_form.cleaned_data["search_year"],
195
values=["title", "author", "year"],
199
books = paginator.get_page(search_form.cleaned_data["page"])
203
book_stats, _ = BookStatistic.objects.get_or_create(
204
book_id=book["id"], user=request.user
209
"title": book["title"],
210
"author": book["author"],
211
"year": book["year"],
212
"statistic": book_stats,
220
"paginator": paginator,
222
"page_name": "books-list",
223
"form": search_form.cleaned_data,
228
def mark_as(request, book_id: str, mark_name: str):
229
if request.method == "POST":
230
book = BookIndex.get(book_id, values=["title"])
233
BookStatistic.objects.update_or_create(
235
mark_name: request.POST.get(mark_name) == "on",
236
"user": request.user,
242
return redirect(reverse("book-about", args=[book_id]))
246
def mark_as_read(request, book_id: str):
247
return mark_as(request, book_id, "read")
251
def mark_as_favorite(request, book_id: str):
252
return mark_as(request, book_id, "favorite")
256
def add_comment(request, book_id: str):
257
if request.method == "POST":
258
book = BookIndex.get(book_id, values=["title"])
262
form = CommentForm(data=request.POST)
264
Comment.objects.create(
267
text=form.cleaned_data["text"],
268
rating=form.cleaned_data["rating"],
271
return redirect(reverse("book-about", args=[book_id]))