taged

Форк
0
/
views.py 
271 строка · 8.3 Кб
1
from datetime import datetime
2

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
11

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
16

17

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):
22
    """
23
    Создаем новую книгу
24
    """
25

26
    def get(self, request):
27
        return render(
28
            request,
29
            "books/create.html",
30
            {
31
                "form": BookCreateFrom(),
32
                "type": "create",
33
                "page_name": "book-create",
34
            },
35
        )
36

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"],
47
            )
48

49
            # Проверка успешности создания книги.
50
            if book:
51
                file: File = request.FILES["book_file"]
52
                book.set_file(file.name, file)
53
                return redirect(reverse("book-about", args=[book.id]))
54

55
        return render(
56
            request,
57
            "books/create.html",
58
            {
59
                "form": book_form,
60
                "type": "create",
61
                "page_name": "book-create",
62
            },
63
        )
64

65

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):
70
    """
71
    Обновляет книгу с заданным book_id данными из запроса.
72
    """
73

74
    def get(self, request, book_id: str):
75
        book = BookIndex.get(book_id)
76
        if book is None:
77
            raise Http404()
78

79
        return render(
80
            request,
81
            "books/create.html",
82
            {
83
                "form": BookCreateFrom(book.json()),
84
                "type": "update",
85
                "page_name": "book-edit",
86
            },
87
        )
88

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"])
95
            if book is None:
96
                raise Http404()
97

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()
103
            book.save()
104

105
            return redirect(reverse("book-about", args=[book.id]))
106

107
        return render(
108
            request,
109
            "books/create.html",
110
            {
111
                "form": book_form,
112
                "type": "update",
113
                "page_name": "book-edit",
114
            },
115
        )
116

117

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):
122
    """
123
    Удаляет книгу с идентификатором book_id.
124
    """
125

126
    def post(self, request, book_id: str):
127
        book = BookIndex.get(book_id, values=["title"])
128

129
        if book is None:
130
            raise Http404()
131

132
        book.delete()
133

134
        return redirect("books-list")
135

136

137
@login_required
138
@elasticsearch_check_available
139
def show(request, book_id):
140
    """
141
    Возвращает файл книги
142
    """
143

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}")
147
    raise Http404()
148

149

150
@login_required
151
@elasticsearch_check_available
152
def about_book(request, book_id):
153
    """
154
    Возвращает описание книги
155
    """
156
    try:
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
162
        )
163

164
        return render(
165
            request,
166
            "books/about_book.html",
167
            {
168
                "book": book,
169
                "statistic": book_stats,
170
                "comments": comments,
171
            },
172
        )
173
    # Перехват исключения, которое выдается, когда книга не найдена.
174
    except es_exceptions.NotFoundError:
175
        raise Http404()
176

177

178
@login_required
179
@elasticsearch_check_available
180
def all_books(request):
181
    """
182
    Список всех книг
183
    """
184

185
    # Создание нового экземпляра класса SearchForm и передача данных request.GET.
186
    search_form = SearchForm(request.GET)
187
    # Проверка корректности запроса и корректности формы поиска.
188
    if not search_form.is_valid():
189
        return HttpResponseRedirect(reverse("books-list"))
190

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"],
196
        sort="published_at",
197
        sort_desc=True,
198
    )
199
    books = paginator.get_page(search_form.cleaned_data["page"])
200

201
    books_list = []
202
    for book in books:
203
        book_stats, _ = BookStatistic.objects.get_or_create(
204
            book_id=book["id"], user=request.user
205
        )
206
        books_list.append(
207
            {
208
                "id": book["id"],
209
                "title": book["title"],
210
                "author": book["author"],
211
                "year": book["year"],
212
                "statistic": book_stats,
213
            }
214
        )
215

216
    return render(
217
        request,
218
        "books/show.html",
219
        {
220
            "paginator": paginator,
221
            "books": books_list,
222
            "page_name": "books-list",
223
            "form": search_form.cleaned_data,
224
        },
225
    )
226

227

228
def mark_as(request, book_id: str, mark_name: str):
229
    if request.method == "POST":
230
        book = BookIndex.get(book_id, values=["title"])
231
        if not book:
232
            raise Http404()
233
        BookStatistic.objects.update_or_create(
234
            defaults={
235
                mark_name: request.POST.get(mark_name) == "on",
236
                "user": request.user,
237
            },
238
            book_id=book_id,
239
            user=request.user,
240
        )
241

242
    return redirect(reverse("book-about", args=[book_id]))
243

244

245
@login_required
246
def mark_as_read(request, book_id: str):
247
    return mark_as(request, book_id, "read")
248

249

250
@login_required
251
def mark_as_favorite(request, book_id: str):
252
    return mark_as(request, book_id, "favorite")
253

254

255
@login_required
256
def add_comment(request, book_id: str):
257
    if request.method == "POST":
258
        book = BookIndex.get(book_id, values=["title"])
259
        if not book:
260
            raise Http404()
261

262
        form = CommentForm(data=request.POST)
263
        if form.is_valid():
264
            Comment.objects.create(
265
                book_id=book_id,
266
                user=request.user,
267
                text=form.cleaned_data["text"],
268
                rating=form.cleaned_data["rating"],
269
            )
270

271
    return redirect(reverse("book-about", args=[book_id]))
272

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.