from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from django.utils import timezone
from django.views.generic import (
DetailView, ListView, CreateView, DeleteView, UpdateView
)
from django.core.paginator import Paginator
from django.contrib.auth.views import PasswordChangeView
from .models import Category, Post, Comment
QUANTITY_OF_POSTS = 10
class BlogListView(ListView):
"""Главная страница."""
model = Post
template_name = 'blog/index.html'
context_object_name = 'post_list'
paginate_by = QUANTITY_OF_POSTS
def get_queryset(self):
return super().get_queryset().select_related(
'category', 'author', 'location'
).filter(
is_published=True,
pub_date__lte=timezone.now(),
category__is_published=True
).order_by('-pub_date')
class PostDetailView(DetailView):
"""Просмотр поста."""
model = Post
template_name = 'blog/detail.html'
context_object_name = 'post'
slug_field = 'slug'
slug_url_kwarg = 'slug'
class CategoryListView(LoginRequiredMixin, ListView):
"""Просмотр категории."""
model = Category
template_name = 'blog/category.html'
context_object_name = 'post_list'
paginate_by = QUANTITY_OF_POSTS
def get_queryset(self):
category_slug = self.kwargs['category_slug']
category = get_object_or_404(
Category,
slug=category_slug,
is_published=True
)
return category.post_set.filter(
is_published=True,
pub_date__lte=timezone.now()
).select_related('category', 'author').order_by('-pub_date')
class ProfileView(LoginRequiredMixin, DetailView):
"""Просмотр профиля пользователя."""
model = User
template_name = 'blog/profile.html'
context_object_name = 'profile'
slug_field = 'username'
slug_url_kwarg = 'username'
paginate_by = QUANTITY_OF_POSTS
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = self.get_object()
is_owner = user == self.request.user
context['is_owner'] = is_owner
if is_owner:
context['edit_profile_url'] = reverse_lazy('edit-profile')
context['change_password_url'] = reverse_lazy('change-password')
posts = Post.objects.filter(author=user).order_by('-pub_date')
else:
posts = Post.objects.filter(
author=user,
category__is_published=True,
pub_date__lte=timezone.now()
).order_by('-pub_date')
paginator = Paginator(posts, self.paginate_by)
page_number = self.request.GET.get('page')
page_obj = paginator.get_page(page_number)
context['page_obj'] = page_obj
return context
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
"""Изменение профиля."""
model = User
template_name = 'blog/user.html'
fields = ['first_name', 'last_name', 'username', 'email']
success_url = reverse_lazy('blog:profile')
def get_object(self, queryset=None):
return self.request.user
class ChangePasswordView(LoginRequiredMixin, PasswordChangeView):
"""Изменение пароля."""
template_name = 'registration/password_change_form.html'
success_url = 'blog:index'
class PostCreateView(LoginRequiredMixin, CreateView):
"""Создание поста."""
model = Post
template_name = 'blog/create.html'
fields = ['title', 'text', 'pub_date', 'location', 'category']
success_url = reverse_lazy('blog/profile.html')
def form_valid(self, form):
if self.request.user.is_authenticated:
form.instance.author = self.request.user
if form.cleaned_data['-pub_date'] > timezone.now():
form.instance.published = False
else:
form.instance.published = True
if form.is_valid():
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('blog:profile', kwargs={'username': self.request.user.username})
class PostEditView(LoginRequiredMixin, UpdateView):
model = Post
template_name = 'blog/create_post.html'
fields = ['title', 'text']
success_url = reverse_lazy('blog:post_list')
class PostDeleteView(LoginRequiredMixin, DeleteView):
"""Удаление поста."""
model = Post
template_name = 'blog/create.html'
success_url = 'blog/index.html'
def dispatch(self, request, *args, **kwargs):
post = get_object_or_404(Post, pk=kwargs['pk'])
if post.author != request.user:
return super().dispatch(request, *args, **kwargs)
class AddCommentView(LoginRequiredMixin, CreateView):
"""Добавление комментария."""
model = Comment
template_name = 'blog/add_comment.html'
fields = ['content']
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.post = get_object_or_404(Post, pk=self.kwargs['pk'])
return super().form_valid(form)
class CommentDeleteView(LoginRequiredMixin, DeleteView):
"""Удаление комментария."""
model = Comment
template_name = 'blog/comment.html'
success_url = 'blog/index.html'
def dispatch(self, request, *args, **kwargs):
comment = get_object_or_404(Comment, pk=kwargs['pk'])
if comment.author != request.user:
return super().dispatch(request, *args, **kwargs)
class CommentUpdateView(LoginRequiredMixin, UpdateView):
"""Изменение комментария."""
model = Comment
template_name = 'blog/comment.html'
slug_field = 'comment'
slug_url_kwarg = 'comment'