128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
from .models import Post, Comment
|
|
from .forms import SearchForm, CommentForm
|
|
from asgiref.sync import async_to_sync
|
|
from django.template.loader import render_to_string
|
|
from django.urls import reverse
|
|
|
|
POST_PER_PAGE = 5
|
|
|
|
|
|
def send_page(self, data={}):
|
|
"""Render HTML and send page to client"""
|
|
|
|
# Prepare context data for page
|
|
page = data["page"]
|
|
context = {}
|
|
data_reverse = {}
|
|
match page:
|
|
case "all posts":
|
|
context = {
|
|
"posts": Post.objects.all()[:POST_PER_PAGE],
|
|
"form": SearchForm(),
|
|
"next_page": 2,
|
|
"is_last_page": (Post.objects.count() // POST_PER_PAGE) == 2,
|
|
}
|
|
case "single post":
|
|
post = Post.objects.get(id=data["id"])
|
|
context = {
|
|
"post": post,
|
|
"form": CommentForm(),
|
|
"comments": Comment.objects.filter(post=post),
|
|
}
|
|
data_reverse = {"slug": post.slug}
|
|
|
|
# Render HTML nav and send to client
|
|
context.update({"active_nav": page})
|
|
self.send_html(
|
|
{
|
|
"selector": "#nav",
|
|
"html": render_to_string("components/_nav.html", context),
|
|
}
|
|
)
|
|
|
|
# Render HTML page and send to client
|
|
template_page = page.replace(" ", "_")
|
|
self.send_html(
|
|
{
|
|
"selector": "#main",
|
|
"html": render_to_string(f"pages/{template_page}.html", context),
|
|
"url": reverse(page, kwargs=data_reverse),
|
|
}
|
|
)
|
|
|
|
|
|
def search(self, data={}):
|
|
"""Search for posts"""
|
|
# Prepare context data for page
|
|
context = {
|
|
"posts": Post.objects.filter(title__icontains=data["search"])[:POST_PER_PAGE]
|
|
}
|
|
|
|
# Render HTML page and send to client
|
|
self.send_html(
|
|
{
|
|
"selector": "#all-posts",
|
|
"html": render_to_string("components/all_posts/list.html", context),
|
|
}
|
|
)
|
|
|
|
|
|
def add_next_posts(self, data={}):
|
|
"""Add next posts from pagination"""
|
|
# Prepare context data for page
|
|
page = int(data["page"]) if "page" in data else 1
|
|
start_of_slice = (page - 1) * POST_PER_PAGE
|
|
end_of_slice = start_of_slice + POST_PER_PAGE
|
|
context = {
|
|
"posts": Post.objects.all()[start_of_slice:end_of_slice],
|
|
"next_page": page + 1,
|
|
"is_last_page": (Post.objects.count() // POST_PER_PAGE) == page,
|
|
}
|
|
|
|
# Add and render HTML with new posts
|
|
self.send_html(
|
|
{
|
|
"selector": "#all-posts",
|
|
"html": render_to_string("components/all_posts/list.html", context),
|
|
"append": True,
|
|
}
|
|
)
|
|
|
|
# Update paginator
|
|
self.send_html(
|
|
{
|
|
"selector": "#paginator",
|
|
"html": render_to_string(
|
|
"components/all_posts/_button_paginator.html", context
|
|
),
|
|
}
|
|
)
|
|
|
|
|
|
def add_comment(self, data):
|
|
"""Add new comment to database"""
|
|
# Add post
|
|
data_with_post = data.copy()
|
|
post = Post.objects.get(id=data["post_id"])
|
|
data_with_post["post"] = post
|
|
# Set initial values by CommentForm
|
|
form = CommentForm(data_with_post)
|
|
# Check if form is valid
|
|
if form.is_valid():
|
|
# Save comment
|
|
form.save()
|
|
# Render HTML with new comment to all clients
|
|
async_to_sync(self.channel_layer.group_send)(
|
|
self.room_name,
|
|
{
|
|
"type": "send.html", # Run "send_html()" method
|
|
"selector": "#comments",
|
|
"html": render_to_string(
|
|
"components/_single_comment.html", {"comment": data}
|
|
),
|
|
"append": True,
|
|
"broadcast": True,
|
|
"url": reverse("single post", kwargs={"slug": post.slug}),
|
|
},
|
|
)
|