add gallery and members to search, delete template, update Redesign

This commit is contained in:
2022-06-14 13:44:56 +00:00
parent 745cd93433
commit 76de1f484e
17 changed files with 215 additions and 55 deletions

View File

@@ -5,6 +5,8 @@ from django.utils import timezone
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .utils import get_image_list
class Album(models.Model): class Album(models.Model):
title = models.CharField(verbose_name="Titel", max_length=200) title = models.CharField(verbose_name="Titel", max_length=200)
@@ -51,3 +53,15 @@ class Album(models.Model):
self.slug = slugify(self.title) self.slug = slugify(self.title)
super().save(*args, **kwargs) super().save(*args, **kwargs)
def get_images(self):
return get_image_list(self.folder_name)
def get_images_length_sub_3(self):
return len(self.get_images()) - 3
def get_model_name(self):
return self._meta.model_name
def get_thumbnail(self):
return None

View File

@@ -0,0 +1,22 @@
from haystack import indexes
from django.utils import timezone
from .models import Album
class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True)
title = indexes.EdgeNgramField(model_attr="title")
description = indexes.EdgeNgramField(model_attr="description", null=True)
status = indexes.CharField(model_attr="status")
event_date = indexes.DateField()
def get_model(self):
return Album
def prepare_event_date(self, obj):
if not obj.event_date:
return timezone.now().date()
return obj.event_date

View File

@@ -9,7 +9,7 @@ from django.utils.text import slugify
from authentications.decorators import authenticated_user from authentications.decorators import authenticated_user
from .models import Album from .models import Album
from .utils import create_thumbs, get_folder_list, get_image_list from .utils import create_thumbs, get_folder_list
def index(request): def index(request):
@@ -21,12 +21,14 @@ def index(request):
if folders: if folders:
for folder in folders: for folder in folders:
if not Album.objects.filter(folder_name=folder): if not Album.objects.filter(folder_name=folder):
album = Album( albums.append(
Album(
title=folder, title=folder,
slug=slugify(folder), slug=slugify(folder),
folder_name=folder, folder_name=folder,
event_date=None, event_date=None,
) )
)
else: else:
# show only PUBLIC albums. # show only PUBLIC albums.
albums = deque( albums = deque(
@@ -34,7 +36,7 @@ def index(request):
) )
for album in list(albums): for album in list(albums):
img_list = get_image_list(album.folder_name) img_list = album.get_images()
if img_list: if img_list:
if album.thumbnail: if album.thumbnail:
for img in img_list: for img in img_list:
@@ -74,7 +76,7 @@ def show_album(request, slug):
else: else:
raise Http404("wrong album slug") raise Http404("wrong album slug")
img_list = get_image_list(album.folder_name) img_list = album.get_images()
if not img_list: if not img_list:
# empty album is temporarily set to DRAFT. # empty album is temporarily set to DRAFT.
album.status = Album.DRAFT album.status = Album.DRAFT

View File

@@ -181,6 +181,9 @@ class Etherpad(models.Model):
return get_pad_html(self.__get_pad_name()) return get_pad_html(self.__get_pad_name())
def get_model_name(self):
return self._meta.model_name
class FileUpload(models.Model): class FileUpload(models.Model):
title = models.CharField(verbose_name="Titel", max_length=128, blank=True) title = models.CharField(verbose_name="Titel", max_length=128, blank=True)

View File

@@ -5,10 +5,10 @@ from .models import Etherpad
class EtherpadIndex(indexes.SearchIndex, indexes.Indexable): class EtherpadIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True)
title = indexes.CharField(model_attr="title") title = indexes.CharField(model_attr="title")
date = indexes.DateField(model_attr="date") date = indexes.DateField(model_attr="date")
etherpad = indexes.EdgeNgramField(null=True) etherpad = indexes.CharField(null=True)
def get_model(self): def get_model(self):
return Etherpad return Etherpad

View File

@@ -104,6 +104,9 @@ class Member(models.Model):
user.first_name = self.firstname user.first_name = self.firstname
user.save() user.save()
def get_model_name(self):
return self._meta.model_name
class JobGroup(models.Model): class JobGroup(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)

View File

@@ -0,0 +1,12 @@
from haystack import indexes
from .models import Member
class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True)
firstname = indexes.EdgeNgramField(model_attr="firstname")
surname = indexes.EdgeNgramField(model_attr="surname")
def get_model(self):
return Member

View File

@@ -216,6 +216,9 @@ class Post(models.Model):
return None return None
return create_pad_for_post(self.slug, "protocol") return create_pad_for_post(self.slug, "protocol")
def get_model_name(self):
return self._meta.model_name
@property @property
def three_tag_names(self): def three_tag_names(self):
return self.tags.names()[:3] return self.tags.names()[:3]

View File

@@ -5,13 +5,13 @@ from .models import Post
class PostIndex(indexes.SearchIndex, indexes.Indexable): class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True)
title = indexes.EdgeNgramField(model_attr="title") title = indexes.EdgeNgramField(model_attr="title")
body = indexes.EdgeNgramField(model_attr="body", null=True) body = indexes.EdgeNgramField(model_attr="body", null=True)
status = indexes.EdgeNgramField(model_attr="status") status = indexes.CharField(model_attr="status")
date = indexes.DateField() date = indexes.DateField()
agenda = indexes.EdgeNgramField(null=True) agenda = indexes.EdgeNgramField()
protocol = indexes.EdgeNgramField(null=True) protocol = indexes.EdgeNgramField()
def get_model(self): def get_model(self):
return Post return Post

View File

@@ -3,7 +3,9 @@ from collections import deque
from haystack.forms import SearchForm from haystack.forms import SearchForm
from haystack.query import SQ from haystack.query import SQ
from gallery.models import Album
from intern.models import Etherpad from intern.models import Etherpad
from members.models import Member
from posts.models import Post from posts.models import Post
@@ -15,6 +17,21 @@ class FetUserSearchForm(SearchForm):
if not self.cleaned_data.get("q"): if not self.cleaned_data.get("q"):
return self.no_query_found() return self.no_query_found()
sqs_gallery = self.searchqueryset.models(Album)
sqs_gallery = sqs_gallery.filter(
SQ(title__icontains=self.cleaned_data["q"])
| SQ(description__icontains=self.cleaned_data["q"])
)
sqs_intern = self.searchqueryset.models(Etherpad)
sqs_intern = sqs_intern.filter(etherpad__icontains=self.cleaned_data["q"])
sqs_member = self.searchqueryset.models(Member)
sqs_member = sqs_member.filter(
SQ(firstname__icontains=self.cleaned_data["q"])
| SQ(surname__icontains=self.cleaned_data["q"])
)
sqs_post = self.searchqueryset.models(Post) sqs_post = self.searchqueryset.models(Post)
sqs_post = sqs_post.filter( sqs_post = sqs_post.filter(
SQ(title__icontains=self.cleaned_data["q"]) SQ(title__icontains=self.cleaned_data["q"])
@@ -23,18 +40,24 @@ class FetUserSearchForm(SearchForm):
| SQ(protocol__icontains=self.cleaned_data["q"]) | SQ(protocol__icontains=self.cleaned_data["q"])
) )
sqs_intern = self.searchqueryset.models(Etherpad) tmp_results = deque([])
sqs_intern = sqs_intern.filter(etherpad__icontains=self.cleaned_data["q"])
results = deque([])
for elem in sqs_post.order_by("-date"):
results.append(elem.object)
for elem in sqs_intern.order_by("-date"): for elem in sqs_intern.order_by("-date"):
tmp_results.append(elem.object)
for elem in sqs_post.order_by("-date"):
tmp_results.append(elem.object)
tmp_results = sorted(tmp_results, key=lambda elem: elem.date, reverse=True)
results = []
for elem in sqs_gallery.order_by("-event_date"):
results.append(elem.object) results.append(elem.object)
return sorted(results, key=lambda elem: elem.date, reverse=True) for elem in sqs_member:
results.append(elem.object)
return results + tmp_results
class NonUserSearchForm(SearchForm): class NonUserSearchForm(SearchForm):
@@ -45,6 +68,18 @@ class NonUserSearchForm(SearchForm):
if not self.cleaned_data.get("q"): if not self.cleaned_data.get("q"):
return self.no_query_found() return self.no_query_found()
sqs_gallery = self.searchqueryset.models(Album).filter(status="20")
sqs_gallery = sqs_gallery.filter(
SQ(title__icontains=self.cleaned_data["q"])
| SQ(description__icontains=self.cleaned_data["q"])
)
sqs_member = self.searchqueryset.models(Member)
sqs_member = sqs_member.filter(
SQ(firstname__icontains=self.cleaned_data["q"])
| SQ(surname__icontains=self.cleaned_data["q"])
)
sqs_post = self.searchqueryset.models(Post).filter(status="20") sqs_post = self.searchqueryset.models(Post).filter(status="20")
sqs_post = sqs_post.filter( sqs_post = sqs_post.filter(
SQ(title__icontains=self.cleaned_data["q"]) SQ(title__icontains=self.cleaned_data["q"])
@@ -52,9 +87,18 @@ class NonUserSearchForm(SearchForm):
| SQ(agenda__icontains=self.cleaned_data["q"]) | SQ(agenda__icontains=self.cleaned_data["q"])
) )
results = deque([]) tmp_results = deque([])
for elem in sqs_post.order_by("-date"): for elem in sqs_post.order_by("-date"):
tmp_results.append(elem.object)
tmp_results = sorted(tmp_results, key=lambda elem: elem.date, reverse=True)
results = []
for elem in sqs_gallery.order_by("-event_date"):
results.append(elem.object) results.append(elem.object)
return sorted(results, key=lambda elem: elem.date, reverse=True) for elem in sqs_member:
results.append(elem.object)
return results + tmp_results

View File

@@ -0,0 +1,21 @@
<a class="flex gap-x-2 rounded group" href="{{ result.get_absolute_url }}">
<div class="flex-none rounded sm:grid grid-cols-2 grid-rows-2 gap-2 hidden">
<div class="rounded aspect-square w-[3.5rem] bg-no-repeat bg-cover" style="background-image: url('{{ result.get_images.0.thumb_url }}');"></div>
<div class="rounded aspect-square w-[3.5rem] bg-no-repeat bg-cover" style="background-image: url('{{ result.get_images.1.thumb_url }}');"></div>
<div class="rounded aspect-square w-[3.5rem] bg-no-repeat bg-cover" style="background-image: url('{{ result.get_images.2.thumb_url }}');"></div>
<div class="rounded aspect-square w-[3.5rem] relative">
<div class="rounded bg-no-repeat bg-cover brightness-[35%] w-full h-full" style="background-image: url('{{ result.get_images.3.thumb_url }}');"></div>
<div class="text-gray-300 md:font-medium bg-transparent absolute w-full h-full top-0 right-0 text-center flex justify-center items-center">
+{{ result.get_images_length_sub_3 }}
</div>
</div>
</div>
<article class="flex-grow-0 sm:m-2">
<h2 class="line-clamp-1 hover:underline decoration-1 text-gray-800 dark:text-gray-200 sm:font-medium"><i class="fa-solid fa-images mr-2"></i>{{ result.title }}</h2>
<div class="line-clamp-2 mt-0.5 text-gray-700 dark:text-gray-300 min-h-12">{{ result.description|safe }}</div>
<div class="mt-1">
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hidden sm:block">{{ result.photographer|default:'' }} am {{ result.event_date }}</small>
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 sm:hidden">{{ result.photographer|default:'' }} am {{ result.event_date|date:"d. M. Y" }}</small>
</div>
</article>
</a>

View File

@@ -0,0 +1,11 @@
<a class="flex gap-x-2 rounded group" href="{{ result.get_absolute_url }}">
<div class="hidden sm:block flex-none rounded aspect-video w-48 bg-center bg-no-repeat bg-cover bg-scale-100 group-hover:bg-scale-110 transition-all ease-in-out duration-300 bg-gray-300 dark:bg-gray-700" style="background-image: url('{{ result.imageurl }}');"></div>
<article class="flex-grow-0 sm:m-2">
<h2 class="line-clamp-1 hover:underline decoration-1 text-gray-800 dark:text-gray-200 sm:font-medium"><i class="fa-solid fa-up-right-from-square mr-2"></i>{{ result.title|truncatechars:50 }}</h2>
<div class="line-clamp-2 mt-0.5 text-gray-700 dark:text-gray-300 min-h-12">{{ result.etherpad_html|safe|truncatechars:120 }}</div>
<div class="mt-1">
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hidden sm:block">Am {{ result.date }}</small>
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 sm:hidden">Am {{ result.date|date:"d. M. Y" }}</small>
</div>
</article>
</a>

View File

@@ -1,33 +1,40 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Suche{% endblock %}
{% block content %} {% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full px-4 my-8 flex-1"> <main class="container mx-auto w-full px-4 my-8 flex-1">
<h1 class="page-title">Suchen</h1> <h1 class="page-title">Suchergebnisse</h1>
<div class="sm:flex sm:flex-row-reverse justify-center text-gray-700 dark:text-gray-200"> <section>
<div class="w-full sticky py-4 md:py-8 -mt-4 md:-mt-8 top-0 z-20 bg-gray-100 dark:bg-gray-900">
<form method="get" action="."> <form method="get" action="." class="flex gap-x-2 mx-auto max-w-prose">
<table> <table>
{{ form.as_table }} <input type="search" id="id_q" name="{{ form.q.name }}" value="{{ form.q.value|default:'' }}" class="block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-blue-200 focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50 placeholder:italic" autofocus placeholder="Frag mich etwas...">
<tr> <input type="submit" class="flex-grow-0 btn btn-primary" value="Suche">
<td>&nbsp;</td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table> </table>
{% if object_list %}
<h3>Results</h3>
{% for result in object_list %}
<p>
<a href="{{ result.get_absolute_url }}">{{ result.date|date }}: {{ result.title }}</a>
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% endif %}
</form> </form>
</div> </div>
{% if form.q.value %}
<div class="mx-auto max-w-prose flex flex-col gap-4">
{% for result in object_list %}
{% if result.get_model_name == 'post' %}
{% include 'search/post.html' %}
{% elif result.get_model_name == 'etherpad' %}
{% include 'search/etherpad.html' %}
{% elif result.get_model_name == 'member' %}
{% include 'search/member.html' %}
{% elif result.get_model_name == 'album' %}
{% include 'search/album.html' %}
{% endif %}
{% empty %}
<article class="flex-grow-0 sm:m-2">
<h2 class="line-clamp-1 decoration-1 text-gray-800 dark:text-gray-200 sm:font-medium"></i>Keine Ergebnisse gefunden.</h2>
</article>
{% endfor %}
</div>
{% endif %}
</section>
</main> </main>
{% endblock %} {% endblock %}

View File

@@ -1,3 +0,0 @@
{{ object.title }}
{{ object.date }}
{{ object.etherpad|safe }}

View File

@@ -1,4 +0,0 @@
{{ object.title }}
{{ object.body|safe }}
{{ object.agenda|safe }}
{{ object.protocol|safe }}

View File

@@ -0,0 +1,10 @@
<a class="flex gap-x-2 group" href="{{ result.get_absolute_url }}">
<div class="flex-none rounded-full aspect-square bg-center bg-no-repeat bg-cover bg-gray-300 dark:bg-gray-700" style="background-image: url('{{ result.image.url }}')"></div>
<article class="flex-grow-0 sm:m-2">
<h2 class="line-clamp-1 hover:underline decoration-1 text-gray-800 dark:text-gray-200 font-medium">{{ result.firstname }} {{ result.surname }}</h2>
<ul class="text-gray-700 dark:text-gray-300 text-sm sm:text-base">
<li><i class="fa-fw fa-solid fa-user-tag text-gray-600 dark:text-gray-400 mr-1" title="Spitzname: "></i>{{ result.nickname }}</li>
<li><i class="fa-fw fa-solid fa-envelope text-gray-600 dark:text-gray-400 mr-1" title="Mailaccount: "></i>{{ result.mailaccount }}</li>
</ul>
</article>
</a>

View File

@@ -0,0 +1,15 @@
<a class="flex gap-x-2 rounded group" href="{{ result.get_absolute_url }}">
<div class="hidden sm:block flex-none rounded aspect-video w-48 bg-center bg-no-repeat bg-cover bg-scale-100 group-hover:bg-scale-110 transition-all ease-in-out duration-300 bg-gray-300 dark:bg-gray-700" style="background-image: url('{{ result.imageurl }}');"></div>
<article class="flex-grow-0 sm:m-2">
<h2 class="line-clamp-1 hover:underline decoration-1 text-gray-800 dark:text-gray-200 sm:font-medium"><i class="fa-solid fa-up-right-from-square mr-2"></i>{{ result.title|truncatechars:50 }}</h2>
{% if result.body %}
<div class="line-clamp-2 mt-0.5 text-gray-700 dark:text-gray-300 min-h-12">{{ result.body|safe|truncatechars:120 }}</div>
{% elif result.agenda_html %}
<div class="line-clamp-2 mt-0.5 text-gray-700 dark:text-gray-300 min-h-12">{{ result.agenda_html|safe|truncatechars:120 }}</div>
{% endif %}
<div class="mt-1">
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hidden sm:block">{{ result.author }} am {{ result.date }}</small>
<small class="text-sm sm:text-base text-gray-600 dark:text-gray-400 sm:hidden">{{ result.author }} am {{ result.date|date:"d. M. Y" }}</small>
</div>
</article>
</a>