diff --git a/apps/participation/models.py b/apps/participation/models.py index 920894a..034abbc 100644 --- a/apps/participation/models.py +++ b/apps/participation/models.py @@ -1,5 +1,7 @@ import re +from django.urls import reverse_lazy + from corres2math.lists import get_sympa_client from django.core.exceptions import ObjectDoesNotExist from django.core.validators import RegexValidator @@ -56,6 +58,9 @@ class Team(models.Model): return super().save(*args, **kwargs) + def get_absolute_url(self): + return reverse_lazy("participation:team_detail", args=(self.pk,)) + def __str__(self): return _("Team {name} ({trigram})").format(name=self.name, trigram=self.trigram) @@ -115,6 +120,9 @@ class Participation(models.Model): verbose_name=_("synthesis video"), ) + def get_absolute_url(self): + return reverse_lazy("participation:team_detail", args=(self.pk,)) + def __str__(self): return _("Participation of the team {name} ({trigram})").format(name=self.team.name, trigram=self.team.trigram) diff --git a/apps/participation/search_indexes.py b/apps/participation/search_indexes.py new file mode 100644 index 0000000..cbe54ed --- /dev/null +++ b/apps/participation/search_indexes.py @@ -0,0 +1,18 @@ +from haystack import indexes + +from .models import Participation, Team, Video + + +class TeamIndex(indexes.SearchIndex, indexes.Indexable): + text = indexes.CharField(document=True, model_attr="name") + trigram = indexes.CharField(model_attr="trigram") + + def get_model(self): + return Team + + +class ParticipationIndex(indexes.SearchIndex, indexes.Indexable): + text = indexes.CharField(document=True, model_attr="team__trigram") + + def get_model(self): + return Participation diff --git a/apps/registration/search_indexes.py b/apps/registration/search_indexes.py new file mode 100644 index 0000000..73c048c --- /dev/null +++ b/apps/registration/search_indexes.py @@ -0,0 +1,13 @@ +from haystack import indexes + +from .models import Registration + + +class RegistrationIndex(indexes.SearchIndex, indexes.Indexable): + text = indexes.CharField(document=True, model_attr="user__username") + last_name = indexes.CharField(model_attr="user__last_name") + first_name = indexes.CharField(model_attr="user__first_name") + email = indexes.CharField(model_attr="user__email") + + def get_model(self): + return Registration diff --git a/corres2math/settings.py b/corres2math/settings.py index 230321f..fbcb0be 100644 --- a/corres2math/settings.py +++ b/corres2math/settings.py @@ -54,6 +54,7 @@ INSTALLED_APPS = [ 'crispy_forms', 'django_extensions', 'django_tables2', + 'haystack', 'logs', 'mailer', 'polymorphic', @@ -181,6 +182,13 @@ CRISPY_TEMPLATE_PACK = 'bootstrap4' DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html' +HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', + 'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'), + } +} + _db_type = os.getenv('DJANGO_DB_TYPE', 'sqlite').lower() if _db_type == 'mysql' or _db_type.startswith('postgres') or _db_type == 'psql': diff --git a/corres2math/urls.py b/corres2math/urls.py index 63efe76..45b3392 100644 --- a/corres2math/urls.py +++ b/corres2math/urls.py @@ -26,6 +26,7 @@ urlpatterns = [ path('admin/doc/', include('django.contrib.admindocs.urls')), path('admin/', admin.site.urls, name="admin"), path('accounts/', include('django.contrib.auth.urls')), + path('search/', include('haystack.urls')), path('api/', include('api.urls')), path('participation/', include('participation.urls')), diff --git a/requirements.txt b/requirements.txt index 8e2482a..5a9bb99 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ django-bootstrap-datepicker-plus django-crispy-forms django-extensions django-filter +django-haystack django-mailer django-polymorphic django-tables2 @@ -10,4 +11,5 @@ djangorestframework django-rest-polymorphic ptpython python-magic -gunicorn \ No newline at end of file +gunicorn +whoosh \ No newline at end of file diff --git a/templates/search/search.html b/templates/search/search.html new file mode 100644 index 0000000..3215f5e --- /dev/null +++ b/templates/search/search.html @@ -0,0 +1,39 @@ +{% extends 'base.html' %} + +{% block content %} +

Search

+ +
+ + {{ form.as_table }} + + + + +
  + +
+ + {% if query %} +

Results

+ + {% for result in page.object_list %} +

+ {{ result.text }} +

+ {% empty %} +

No results found.

+ {% endfor %} + + {% if page.has_previous or page.has_next %} +
+ {% if page.has_previous %}{% endif %}« Previous{% if page.has_previous %}{% endif %} + | + {% if page.has_next %}{% endif %}Next »{% if page.has_next %}{% endif %} +
+ {% endif %} + {% else %} + {# Show some example queries to run, maybe query syntax, something else? #} + {% endif %} +
+{% endblock %} \ No newline at end of file