blender-studio/blog/views/blog.py
Pablo Vazquez b64e5d8a81 Add PaginatedViewMixin in Blog an ProductionLog
The new mixin provides a 3-page (instead of a 2-page) paginator for
the Blog and Production Log views. The legacy month-based views for
Production Logs have been kept for now, but they are not accessible.

Co-authored by: @fsiddi
2024-08-15 20:01:43 +02:00

94 lines
3.0 KiB
Python

"""Views that render blog pages are defined here."""
from typing import List
from django.contrib.syndication.views import Feed
from django.db.models.query import QuerySet
from django.utils import feedgenerator
from django.views.generic import ListView, DetailView
from blog.models import Post, Like
from blog.queries import get_posts
from comments.models import Comment
from comments.queries import get_annotated_comments
from comments.views.common import comments_to_template_type
import common.queries
from common.mixins import PaginatedViewMixin
class PostList(PaginatedViewMixin):
model = Post
context_object_name = 'posts'
paginate_by = 12
def get_queryset(self) -> QuerySet:
return get_posts(
user_pk=self.request.user.pk if self.request.user.is_authenticated else None
)
class PostDetail(DetailView):
model = Post
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post: Post = self.object
show_subscribe_instead = post.is_subscribers_only and (
self.request.user.is_anonymous
or (
# This is neither the author of the post nor a subscriber
self.request.user.pk != post.author_id
and not common.queries.has_active_subscription(self.request.user)
)
)
if self.request.user.is_authenticated:
post.liked = Like.objects.filter(post_id=post.pk, user_id=self.request.user.pk).exists()
# Whether the subscribe banner should be displayed instead of content
context['show_subscribe_instead'] = show_subscribe_instead
# Display edit buttons for editors/authors
context['user_can_edit_post'] = self.request.user.is_staff and self.request.user.has_perm(
'blog.change_post'
)
if post.film and post.author.film_crew.filter(film=post.film):
context['user_film_role'] = post.author.film_crew.filter(film=post.film)[0].role
# Comment threads are only shown when post is visible
if not show_subscribe_instead:
comments: List[Comment] = get_annotated_comments(post, self.request.user.pk)
context['comments'] = comments_to_template_type(
comments, post.comment_url, self.request.user
)
return context
class PostFeed(Feed):
title = 'Blender Studio feed'
link = '/blog/'
description = 'Updates from Blender Studio'
def item_enclosures(self, item: Post):
return [
feedgenerator.Enclosure(
item.thumbnail_s_url,
str(item.thumbnail.size),
'image/{}'.format(item.thumbnail.name.split('.')[-1]),
)
]
def items(self):
return Post.objects.filter(is_published=True, is_subscribers_only=False).order_by(
'-date_published'
)[:5]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.excerpt