gawa/gawa/blog/views.py
2023-10-07 19:43:32 +02:00

153 lines
5.5 KiB
Python

import json
import ast
from django.shortcuts import get_object_or_404, render
from django.http.response import Http404, HttpResponse
from django.http.request import HttpRequest
from django.utils.translation import get_language
from django.views.generic import TemplateView, DetailView, ListView, View
from django.db.models import Q
from .models import BlogPost, Category, Keyword
from start.views import SearchableView
import logging
logger = logging.getLogger(__name__)
class Index(TemplateView, SearchableView):
"""
The index page of the gawa/blog app.
Utilizes a generic view, because I will do so for all views,
a regular view function would suffice.
"""
template_name: str = "blog/index.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['featured_posts'] = BlogPost.objects.filter(
featured=True, public=True)
return context
class Post(DetailView):
"""
Main page of a blog post
"""
model = BlogPost
template_name = "blog/blogpost.html"
context_object_name = "post"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['featured_posts'] = BlogPost.objects.filter(featured=True)
return context
class Browse(ListView):
"""
Scroll through a list of blog posts
There should also be some kind of filter, for category and date.
Of course, Articles will also show up in the MainSearchView
"""
model = BlogPost
template_name = "blog/browse.html"
context_object_name = "posts"
allow_empty = False # but we have a special get method
def get_queryset(self):
objects = BlogPost.objects.all()
if "category" in self.request.GET and len(
self.request.GET["category"].strip()) > 0:
category = self.request.GET["category"]
try:
category = Category.objects.get(slug=category)
objects = objects.filter(category=category)
except Category.DoesNotExist:
objects = objects.none()
if "search" in self.request.GET and len(
self.request.GET["search"].strip()) > 0:
search = self.request.GET["search"]
# __icontains matches those attributes that contain the
# search string without caring about lower/upper cases
objects = objects.filter(
Q(title_en__icontains=search) |
Q(title_de__icontains=search) |
Q(subtitle_en__icontains=search) |
Q(subtitle_de__icontains=search) |
Q(desc_en__icontains=search) |
Q(desc_de__icontains=search) |
# Q(body_en__icontains=search) |
# Q(body_de__icontains=search) |
Q(slug__icontains=search)
)
if "keywords" in self.request.GET and len(
self.request.GET["keywords"].strip()) > 0:
raw_keywords = self.request.GET["keywords"]
raw_keywords = raw_keywords.split('+')
keywords: list[Keyword] = []
for raw_keyword in raw_keywords:
try:
keywords.append(Keyword.objects.get(slug=raw_keyword))
except Keyword.DoesNotExist:
pass
logger.debug(f"found kws: {keywords}")
objects = objects.filter(keywords__in=keywords)
return objects
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['featured_posts'] = BlogPost.objects.filter(featured=True)
context['categories'] = Category.objects.all()
context['keywords'] = Keyword.objects.all()
context["filters"] = {}
if "category" in self.request.GET and len(
self.request.GET["category"].strip()) > 0:
category = self.request.GET["category"]
try:
category = Category.objects.get(slug=category)
context["filters"]["category"] = category
except Category.DoesNotExist:
context["filters"]["category"] = None
if "search" in self.request.GET and len(
self.request.GET["search"].strip()) > 0:
search = self.request.GET["search"]
context["filters"]["search"] = search
if "keywords" in self.request.GET and len(
self.request.GET["keywords"].strip()) > 0:
keywords = self.request.GET["keywords"]
keywords = keywords.split('+')
context["filters"]["keywords"] = keywords
return context
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty:
# When pagination is enabled and object_list is a queryset,
# it's better to do a cheap query than to load the unpaginated
# queryset in memory.
if self.get_paginate_by(self.object_list) is not None and hasattr(
self.object_list, 'exists'):
is_empty = not self.object_list.exists()
else:
is_empty = not self.object_list
else:
is_empty = False
context = self.get_context_data()
context["is_empty"] = is_empty
response = self.render_to_response(context)
if is_empty:
response.status_code = 404
return response