From cf70474b4fe06cab8948d1fe748d2596db8f83e6 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Wed, 31 May 2023 23:29:46 +0200 Subject: [PATCH] work on searchability --- gawa/blog/migrations/0001_initial.py | 31 +++++++++++ gawa/blog/models.py | 5 +- gawa/blog/urls.py | 2 +- gawa/blog/views.py | 17 +++++- .../migrations/0002_auto_20230531_2254.py | 37 +++++++++++++ gawa/start/models.py | 52 ++++++++++++++++--- gawa/start/urls.py | 10 ++-- gawa/start/views.py | 30 ++++++++--- 8 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 gawa/blog/migrations/0001_initial.py create mode 100644 gawa/start/migrations/0002_auto_20230531_2254.py diff --git a/gawa/blog/migrations/0001_initial.py b/gawa/blog/migrations/0001_initial.py new file mode 100644 index 0000000..8981bef --- /dev/null +++ b/gawa/blog/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 3.2.19 on 2023-05-31 20:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('start', '0002_auto_20230531_2254'), + ] + + operations = [ + migrations.CreateModel( + name='BlogPost', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50)), + ('subtitle', models.CharField(max_length=50)), + ('desc', models.CharField(max_length=250, unique=True)), + ('body', models.TextField()), + ('date', models.DateField(blank=True)), + ('slug', models.SlugField()), + ('keywords', models.ManyToManyField(to='start.Keyword')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/gawa/blog/models.py b/gawa/blog/models.py index 76582a7..b0de991 100644 --- a/gawa/blog/models.py +++ b/gawa/blog/models.py @@ -1,6 +1,8 @@ from django.db import models -class BlogPost(models.Model): +from start.models import AbstractSearchable + +class BlogPost(AbstractSearchable): """ Should contain a blogpost """ @@ -9,3 +11,4 @@ class BlogPost(models.Model): desc = models.CharField(max_length=250, unique=True) body = models.TextField() date = models.DateField(blank=True) + slug = models.SlugField() diff --git a/gawa/blog/urls.py b/gawa/blog/urls.py index 154fb7d..fbc2c43 100644 --- a/gawa/blog/urls.py +++ b/gawa/blog/urls.py @@ -3,5 +3,5 @@ from django.urls import path from . import views urlpatterns = [ - path("", views.IndexView.as_view(), name="BlogIndex"), + path("", views.Index.as_view(), name="BlogIndex"), ] diff --git a/gawa/blog/views.py b/gawa/blog/views.py index 1cf3362..f254332 100644 --- a/gawa/blog/views.py +++ b/gawa/blog/views.py @@ -1,7 +1,9 @@ from django.shortcuts import render -from django.views.generic.base import TemplateView +from django.views.generic import TemplateView, DetailView, ListView, View -class IndexView(TemplateView): +from start.views import SearchableView + +class Index(TemplateView, SearchableView): """ The index page of the gawa/blog app. @@ -11,3 +13,14 @@ class IndexView(TemplateView): template_name: str = "blog/index.html" +class Post(DetailView): + """ + Main page of a blog post + """ + pass + +class List(ListView): + """ + Scroll through a list of blog posts + """ + pass diff --git a/gawa/start/migrations/0002_auto_20230531_2254.py b/gawa/start/migrations/0002_auto_20230531_2254.py new file mode 100644 index 0000000..694756f --- /dev/null +++ b/gawa/start/migrations/0002_auto_20230531_2254.py @@ -0,0 +1,37 @@ +# Generated by Django 3.2.19 on 2023-05-31 20:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('start', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Keyword', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.CharField(max_length=40)), + ], + ), + migrations.CreateModel( + name='StaticSite', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50)), + ('subtitle', models.CharField(max_length=50)), + ('desc', models.CharField(max_length=250, unique=True)), + ('date', models.DateField(blank=True)), + ('keywords', models.ManyToManyField(to='start.Keyword')), + ], + options={ + 'abstract': False, + }, + ), + migrations.DeleteModel( + name='MainSearchEntry', + ), + ] diff --git a/gawa/start/models.py b/gawa/start/models.py index 039c82e..b9d76a0 100644 --- a/gawa/start/models.py +++ b/gawa/start/models.py @@ -1,16 +1,56 @@ from django.db import models +from django.db.models.options import override -class MainSearchEntry(models.Model): +#from .views import SearchableView +# ^^^ raises Circular Import + +class Keyword(models.Model): """ - This model will be searched for by the searchbox that is in every upper part of the website. - The view making use of it is MainSearchView. + this is the model that should contain searchable keywords + """ + text = models.CharField(max_length=40) - Any model object that I implement as searchable should eventually have an entry here. +class AbstractSearchable(models.Model): + """ + Abstract class for any model that should be searchable. + This model will be searched for by the searchbox that is in every upper part of the website. """ title = models.CharField(max_length=50) subtitle = models.CharField(max_length=50) desc = models.CharField(max_length=250, unique=True) # may be empty/blank for some entries date = models.DateField(blank=True) - # every searchable object should have some url associated with it. - link = models.URLField() + keywords = models.ManyToManyField(Keyword) + + class Meta: + """ + AbstractSearchable is an abstract model + """ + abstract = True + + @classmethod + def regenerate_all_entries(cls): + """ + regenerate all searchable items + """ + raise NotImplementedError + +class StaticSite(AbstractSearchable): + """ + This model represents any static site, such as start:index, + that should show up in search. + + Every searchable view should inherit from start.views.SearchableView. + # TODO automate scanning for SearchableView classes + """ + + + @override + def regenerate_all_entries(cls): + + # this does not actually contain all views, only those that should show + # up in the search. + # TODO automate searching for these + #all_views: list[SearchableView] = [] + + raise NotImplementedError diff --git a/gawa/start/urls.py b/gawa/start/urls.py index d9ce09f..9969463 100644 --- a/gawa/start/urls.py +++ b/gawa/start/urls.py @@ -4,9 +4,9 @@ from . import views app_name: str = "start" urlpatterns = [ - path("", views.IndexView.as_view(), name="index"), - path("search/", views.MainSearchView.as_view(), name="search"), - path("legal/", views.LegalInfoView.as_view(), name="legal_info"), - path("professional/", views.LegalInfoView.as_view(), name="professional"), - path('language/activate//', views.ActivateLanguageView.as_view(), name='activate_language'), + path("", views.Index.as_view(), name="index"), + path("search/", views.MainSearch.as_view(), name="search"), + path("legal/", views.LegalInfo.as_view(), name="legal_info"), + path("professional/", views.LegalInfo.as_view(), name="professional"), + path('language/activate//', views.ActivateLanguage.as_view(), name='activate_language'), ] diff --git a/gawa/start/views.py b/gawa/start/views.py index 8300ce2..216ceed 100644 --- a/gawa/start/views.py +++ b/gawa/start/views.py @@ -10,10 +10,24 @@ from django.views import View from django.template import Template, context, loader from django.http import HttpResponseRedirect from django.shortcuts import render -from .forms import MainSearchForm -from .models import MainSearchEntry -class IndexView(TemplateView): +from .forms import MainSearchForm +from .models import AbstractSearchable + +from abc import ABC + +class SearchableView(View, ABC): + """ + This abstract view implements some traits of views that should show up + in the main search + """ + title: str + subtitle: str + desc: str + date: None = None + keywords: list[str] + +class Index(TemplateView, SearchableView): """ The index page of the gawa app. @@ -28,7 +42,7 @@ class IndexView(TemplateView): context["MainSearchForm"] = MainSearchForm() return context -class ProfessionalView(TemplateView): +class Professional(TemplateView, SearchableView): """ Professional informations that might interest a professional employer """ @@ -40,7 +54,7 @@ class ProfessionalView(TemplateView): context["MainSearchForm"] = MainSearchForm() return context -class LegalInfoView(TemplateView): +class LegalInfo(TemplateView, SearchableView): """ Legal info that the german authorities want. """ @@ -52,7 +66,7 @@ class LegalInfoView(TemplateView): context["MainSearchForm"] = MainSearchForm() return context -class ActivateLanguageView(View): +class ActivateLanguage(View): """ Set the language to whatever """ @@ -66,12 +80,12 @@ class ActivateLanguageView(View): request.session[translation.LANGUAGE_SESSION_KEY] = self.language_code return redirect(self.redirect_to) -class MainSearchView(ListView): +class MainSearch(ListView): """ Search for anything. """ - model = MainSearchEntry + model = AbstractSearchable object_list = [] # this is only declaration, the view breaks without it. template_name: str = "start/search.html"