Browse Source

kostra projektu

master
mist 4 years ago
parent
commit
3e96abedc9
  1. 39
      .dockerignore
  2. 60
      Dockerfile
  3. 11
      Pipfile
  4. 0
      home/__init__.py
  5. 22
      home/migrations/0001_initial.py
  6. 62
      home/migrations/0002_create_homepage.py
  7. 56
      home/migrations/0003_auto_20210317_0555.py
  8. 0
      home/migrations/__init__.py
  9. 41
      home/models.py
  10. 204
      home/static/css/welcome_page.css
  11. 14
      home/templates/home/home_page.html
  12. 0
      hvezdarna/__init__.py
  13. 0
      hvezdarna/settings/__init__.py
  14. 162
      hvezdarna/settings/base.py
  15. 18
      hvezdarna/settings/dev.py
  16. 8
      hvezdarna/settings/production.py
  17. 0
      hvezdarna/static/css/hvezdarna.css
  18. 0
      hvezdarna/static/css/hvezdarna.less
  19. 0
      hvezdarna/static/js/hvezdarna.js
  20. 9
      hvezdarna/templates/404.html
  21. 13
      hvezdarna/templates/500.html
  22. 65
      hvezdarna/templates/base.html
  23. 39
      hvezdarna/urls.py
  24. 16
      hvezdarna/wsgi.py
  25. 10
      manage.py
  26. 2
      requirements.txt
  27. 0
      search/__init__.py
  28. 38
      search/templates/search/search.html
  29. 34
      search/views.py

39
.dockerignore

@ -0,0 +1,39 @@
# Django project
/media/
/static/
*.sqlite3
# Python and others
__pycache__
*.pyc
.DS_Store
*.swp
/venv/
/tmp/
/.vagrant/
/Vagrantfile.local
node_modules/
/npm-debug.log
/.idea/
.vscode
coverage
.python-version
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

60
Dockerfile

@ -0,0 +1,60 @@
# Use an official Python runtime based on Debian 10 "buster" as a parent image.
FROM python:3.8.1-slim-buster
# Add user that will be used in the container.
RUN useradd wagtail
# Port used by this container to serve HTTP.
EXPOSE 8000
# Set environment variables.
# 1. Force Python stdout and stderr streams to be unbuffered.
# 2. Set PORT variable that is used by Gunicorn. This should match "EXPOSE"
# command.
ENV PYTHONUNBUFFERED=1 \
PORT=8000
# Install system packages required by Wagtail and Django.
RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \
build-essential \
libpq-dev \
libmariadbclient-dev \
libjpeg62-turbo-dev \
zlib1g-dev \
libwebp-dev \
&& rm -rf /var/lib/apt/lists/*
# Install the application server.
RUN pip install "gunicorn==20.0.4"
# Install the project requirements.
COPY requirements.txt /
RUN pip install -r /requirements.txt
# Use /app folder as a directory where the source code is stored.
WORKDIR /app
# Set this directory to be owned by the "wagtail" user. This Wagtail project
# uses SQLite, the folder needs to be owned by the user that
# will be writing to the database file.
RUN chown wagtail:wagtail /app
# Copy the source code of the project into the container.
COPY --chown=wagtail:wagtail . .
# Use user "wagtail" to run the build commands below and the server itself.
USER wagtail
# Collect static files.
RUN python manage.py collectstatic --noinput --clear
# Runtime command that executes when "docker run" is called, it does the
# following:
# 1. Migrate the database.
# 2. Start the application server.
# WARNING:
# Migrating database at the same time as starting the server IS NOT THE BEST
# PRACTICE. The database should be migrated manually or using the release
# phase facilities of your hosting platform. This is used only so the
# Wagtail instance can be started with a simple "docker run" command.
CMD set -xe; python manage.py migrate --noinput; gunicorn hvezdarna.wsgi:application

11
Pipfile

@ -0,0 +1,11 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
[requires]
python_version = "3.8"

0
home/__init__.py

22
home/migrations/0001_initial.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wagtailcore', '0040_page_draft_title'),
]
operations = [
migrations.CreateModel(
name='HomePage',
fields=[
('page_ptr', models.OneToOneField(on_delete=models.CASCADE, parent_link=True, auto_created=True, primary_key=True, serialize=False, to='wagtailcore.Page')),
],
options={
'abstract': False,
},
bases=('wagtailcore.page',),
),
]

62
home/migrations/0002_create_homepage.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from django.db import migrations
def create_homepage(apps, schema_editor):
# Get models
ContentType = apps.get_model('contenttypes.ContentType')
Page = apps.get_model('wagtailcore.Page')
Site = apps.get_model('wagtailcore.Site')
HomePage = apps.get_model('home.HomePage')
# Delete the default homepage
# If migration is run multiple times, it may have already been deleted
Page.objects.filter(id=2).delete()
# Create content type for homepage model
homepage_content_type, __ = ContentType.objects.get_or_create(
model='homepage', app_label='home')
# Create a new homepage
homepage = HomePage.objects.create(
title="Home",
draft_title="Home",
slug='home',
content_type=homepage_content_type,
path='00010001',
depth=2,
numchild=0,
url_path='/home/',
)
# Create a site with the new homepage set as the root
Site.objects.create(
hostname='localhost', root_page=homepage, is_default_site=True)
def remove_homepage(apps, schema_editor):
# Get models
ContentType = apps.get_model('contenttypes.ContentType')
HomePage = apps.get_model('home.HomePage')
# Delete the default homepage
# Page and Site objects CASCADE
HomePage.objects.filter(slug='home', depth=2).delete()
# Delete content type for homepage model
ContentType.objects.filter(model='homepage', app_label='home').delete()
class Migration(migrations.Migration):
run_before = [
('wagtailcore', '0053_locale_model'),
]
dependencies = [
('home', '0001_initial'),
]
operations = [
migrations.RunPython(create_homepage, remove_homepage),
]

56
home/migrations/0003_auto_20210317_0555.py

@ -0,0 +1,56 @@
# Generated by Django 3.1.7 on 2021-03-17 05:55
from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields
import wagtail.core.fields
class Migration(migrations.Migration):
dependencies = [
('wagtailimages', '0023_add_choose_permissions'),
('home', '0002_create_homepage'),
]
operations = [
migrations.AddField(
model_name='homepage',
name='address',
field=models.CharField(blank=True, default='', max_length=255, verbose_name='Adresa'),
),
migrations.AddField(
model_name='homepage',
name='body',
field=wagtail.core.fields.RichTextField(blank=True),
),
migrations.AddField(
model_name='homepage',
name='email',
field=models.EmailField(blank=True, max_length=64, null=True, verbose_name='E-mail'),
),
migrations.AddField(
model_name='homepage',
name='map_link',
field=models.URLField(blank=True, default='', max_length=128, verbose_name='Odkaz na mapu'),
),
migrations.AddField(
model_name='homepage',
name='mobile',
field=models.CharField(blank=True, default='', max_length=24, verbose_name='Mobil'),
),
migrations.CreateModel(
name='CarouselImage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('caption', models.CharField(blank=True, max_length=250)),
('image', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailimages.image')),
('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='carousel_images', to='home.homepage')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
]

0
home/migrations/__init__.py

41
home/models.py

@ -0,0 +1,41 @@
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.core.models import Page, Orderable
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.search import index
class HomePage(Page):
body = RichTextField(blank=True)
address = models.CharField(max_length=255, verbose_name="Adresa", blank=True, default='')
mobile = models.CharField(max_length=24, verbose_name="Mobil", blank=True, default='')
email = models.EmailField(max_length=64, verbose_name="E-mail", blank=True, null=True)
map_link = models.URLField(max_length=128, verbose_name="Odkaz na mapu", blank=True, default='')
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
FieldPanel('address'),
FieldPanel('mobile'),
FieldPanel('email'),
FieldPanel('map_link'),
InlinePanel('carousel_images', label="Obrázky"),
]
search_fields = Page.search_fields + [
index.SearchField('body'),
]
class CarouselImage(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='carousel_images')
image = models.ForeignKey('wagtailimages.Image', on_delete=models.CASCADE, related_name='+')
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption'),
]

204
home/static/css/welcome_page.css

@ -0,0 +1,204 @@
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
max-width: 960px;
min-height: 100vh;
margin: 0 auto;
padding: 0 15px;
color: #231f20;
font-family: 'Helvetica Neue', 'Segoe UI', Arial, sans-serif;
line-height: 1.25;
}
a {
background-color: transparent;
color: #308282;
text-decoration: underline;
}
a:hover {
color: #ea1b10;
}
h1,
h2,
h3,
h4,
h5,
p,
ul {
padding: 0;
margin: 0;
font-weight: 400;
}
main {
display: block; /* For IE11 support */
}
svg:not(:root) {
overflow: hidden;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #e6e6e6;
}
.logo {
width: 150px;
margin-right: 20px;
}
.logo a {
display: block;
}
.figure-logo {
max-width: 150px;
max-height: 55.1px;
}
.release-notes {
font-size: 14px;
}
.main {
padding: 40px 0;
margin: 0 auto;
text-align: center;
}
.figure-space {
max-width: 265px;
}
@-webkit-keyframes pos {
0%, 100% {
-webkit-transform: rotate(-6deg);
transform: rotate(-6deg);
}
50% {
-webkit-transform: rotate(6deg);
transform: rotate(6deg);
}
}
@keyframes pos {
0%, 100% {
-webkit-transform: rotate(-6deg);
transform: rotate(-6deg);
}
50% {
-webkit-transform: rotate(6deg);
transform: rotate(6deg);
}
}
.egg {
fill: #43b1b0;
-webkit-animation: pos 3s ease infinite;
animation: pos 3s ease infinite;
-webkit-transform: translateY(50px);
transform: translateY(50px);
-webkit-transform-origin: 50% 80%;
transform-origin: 50% 80%;
}
.main-text {
max-width: 400px;
margin: 5px auto;
}
.main-text h1 {
font-size: 22px;
}
.main-text p {
margin: 15px auto 0;
}
.footer {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
border-top: 1px solid #e6e6e6;
padding: 10px;
}
.option {
display: block;
padding: 10px 10px 10px 34px;
position: relative;
text-decoration: none;
}
.option svg {
width: 24px;
height: 24px;
fill: gray;
border: 1px solid #d9d9d9;
padding: 5px;
border-radius: 100%;
top: 10px;
left: 0;
position: absolute;
}
.option h4 {
font-size: 19px;
text-decoration: underline;
}
.option p {
padding-top: 3px;
color: #231f20;
font-size: 15px;
font-weight: 300;
}
@media (max-width: 996px) {
body {
max-width: 780px;
}
}
@media (max-width: 767px) {
.option {
flex: 0 0 50%;
}
}
@media (max-width: 599px) {
.main {
padding: 20px 0;
}
.figure-space {
max-width: 200px;
}
.footer {
display: block;
width: 300px;
margin: 0 auto;
}
}
@media (max-width: 360px) {
.header-link {
max-width: 100px;
}
}

14
home/templates/home/home_page.html

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% load static %}
{% block body_class %}template-homepage{% endblock %}
{% block extra_css %}
{% endblock extra_css %}
{% block content %}
{% endblock content %}

0
hvezdarna/__init__.py

0
hvezdarna/settings/__init__.py

162
hvezdarna/settings/base.py

@ -0,0 +1,162 @@
"""
Django settings for hvezdarna project.
Generated by 'django-admin startproject' using Django 3.1.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(PROJECT_DIR)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# Application definition
INSTALLED_APPS = [
'home',
'search',
'wagtail.contrib.forms',
'wagtail.contrib.redirects',
'wagtail.embeds',
'wagtail.sites',
'wagtail.users',
'wagtail.snippets',
'wagtail.documents',
'wagtail.images',
'wagtail.search',
'wagtail.admin',
'wagtail.core',
'modelcluster',
'taggit',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'wagtail.contrib.redirects.middleware.RedirectMiddleware',
]
ROOT_URLCONF = 'hvezdarna.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(PROJECT_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'hvezdarna.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [
os.path.join(PROJECT_DIR, 'static'),
]
# ManifestStaticFilesStorage is recommended in production, to prevent outdated
# JavaScript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
# See https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
# Wagtail settings
WAGTAIL_SITE_NAME = "hvezdarna"
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
BASE_URL = 'http://example.com'

18
hvezdarna/settings/dev.py

@ -0,0 +1,18 @@
from .base import *
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'ec1zzak-x$@r3(03&$#+up6u7pg-e0ybp%dl*j3il%s_c_x_ql'
# SECURITY WARNING: define the correct hosts in production!
ALLOWED_HOSTS = ['*']
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
try:
from .local import *
except ImportError:
pass

8
hvezdarna/settings/production.py

@ -0,0 +1,8 @@
from .base import *
DEBUG = False
try:
from .local import *
except ImportError:
pass

0
hvezdarna/static/css/hvezdarna.css

0
hvezdarna/static/css/hvezdarna.less

0
hvezdarna/static/js/hvezdarna.js

9
hvezdarna/templates/404.html

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block body_class %}template-404{% endblock %}
{% block content %}
<h1>Page not found</h1>
<h2>Sorry, this page could not be found.</h2>
{% endblock %}

13
hvezdarna/templates/500.html

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8" />
<title>Internal server error</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<h1>Internal server error</h1>
<h2>Sorry, there seems to be an error. Please try again soon.</h2>
</body>
</html>

65
hvezdarna/templates/base.html

@ -0,0 +1,65 @@
{% load static wagtailuserbar %}
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<title>
{% block title %}
{% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}
{% endblock %}
{% block title_suffix %}
{% with self.get_site.site_name as site_name %}
{% if site_name %}- {{ site_name }}{% endif %}
{% endwith %}
{% endblock %}
</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{# Global stylesheets #}
{#<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">#}
<link rel="stylesheet" type="text/css" href="{% static 'css/hvezdarna.css' %}">
{% block extra_css %}
{# Override this in templates to add extra stylesheets #}
{% endblock %}
</head>
<body class="{% block body_class %}{% endblock %}">
{% wagtailuserbar %}
<div class="container-fluid">
<nav class="navbar navbar-expand-lg p-4 d-block d-md-flex">
<a href="/" class="navbar-brand d-block text-center d-md-inline">
LOGO
</a>
<ul class="navbar-nav nav-info-text">
<li class="nav-item">
<a href="mailto:{{ page.email }}">{{ page.email }}</a>
</li>
<li class="nav-item">|</li>
<li class="nav-item">
<a href="mailto:{{ page.address }}">{{ page.address }}</a>
</li>
<li class="nav-item">|</li>
<li class="nav-item">
<a href="mailto:{{ page.mobile }}">{{ page.mobile }}</a>
</li>
</ul>
</nav>
<hr>
</div>
{% block content %}{% endblock %}
{# Global javascript #}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<script type="text/javascript" src="{% static 'js/hvezdarna.js' %}"></script>
{% block extra_js %}
{# Override this in templates to add extra javascript #}
{% endblock %}
</body>
</html>

39
hvezdarna/urls.py

@ -0,0 +1,39 @@
from django.conf import settings
from django.urls import include, path
from django.contrib import admin
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
urlpatterns = [
path('django-admin/', admin.site.urls),
path('admin/', include(wagtailadmin_urls)),
path('documents/', include(wagtaildocs_urls)),
path('search/', search_views.search, name='search'),
]
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# Serve static and media files from development server
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns = urlpatterns + [
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
path("", include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# path("pages/", include(wagtail_urls)),
]

16
hvezdarna/wsgi.py

@ -0,0 +1,16 @@
"""
WSGI config for hvezdarna project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hvezdarna.settings.dev")
application = get_wsgi_application()

10
manage.py

@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hvezdarna.settings.dev")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

2
requirements.txt

@ -0,0 +1,2 @@
Django>=3.1,<3.2
wagtail>=2.12,<2.13

0
search/__init__.py

38
search/templates/search/search.html

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% load static wagtailcore_tags %}
{% block body_class %}template-searchresults{% endblock %}
{% block title %}Search{% endblock %}
{% block content %}
<h1>Search</h1>
<form action="{% url 'search' %}" method="get">
<input type="text" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
<input type="submit" value="Search" class="button">
</form>
{% if search_results %}
<ul>
{% for result in search_results %}
<li>
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
{% if result.search_description %}
{{ result.search_description }}
{% endif %}
</li>
{% endfor %}
</ul>
{% if search_results.has_previous %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.previous_page_number }}">Previous</a>
{% endif %}
{% if search_results.has_next %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.next_page_number }}">Next</a>
{% endif %}
{% elif search_query %}
No results found
{% endif %}
{% endblock %}

34
search/views.py

@ -0,0 +1,34 @@
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.template.response import TemplateResponse
from wagtail.core.models import Page
from wagtail.search.models import Query
def search(request):
search_query = request.GET.get('query', None)
page = request.GET.get('page', 1)
# Search
if search_query:
search_results = Page.objects.live().search(search_query)
query = Query.get(search_query)
# Record hit
query.add_hit()
else:
search_results = Page.objects.none()
# Pagination
paginator = Paginator(search_results, 10)
try:
search_results = paginator.page(page)
except PageNotAnInteger:
search_results = paginator.page(1)
except EmptyPage:
search_results = paginator.page(paginator.num_pages)
return TemplateResponse(request, 'search/search.html', {
'search_query': search_query,
'search_results': search_results,
})
Loading…
Cancel
Save