Compare commits

..

15 Commits

Author SHA1 Message Date
WGAVermeer
0380bdb4a6 updated docs
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-07-13 13:15:29 +02:00
65df741514 Update docs/ROADMAP.md
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-07-13 06:46:11 +00:00
07d805788e Update docs/ROADMAP.md
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-07-13 06:45:34 +00:00
12ed8e62f8 Update docs/ROADMAP.md
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-07-13 06:09:37 +00:00
df04350128 Update docs/ROADMAP.md
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-07-13 06:06:36 +00:00
b1f38cc9d9 Update README.md
Some checks failed
Gitea Test. / tests (push) Failing after 11s
2026-07-13 05:57:31 +00:00
Wouter Vermeer
99c0b4ae6d cleanup and slight nav-bar additions.
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-04-30 19:33:22 +02:00
Wouter Vermeer
33661e14da added Core for core pages, added static files & templates.
Some checks failed
Gitea Test. / tests (push) Failing after 3s
2026-04-30 17:48:33 +02:00
Wouter Vermeer
bef2577746 moved DEBUG variable into compose files. 2026-04-30 17:47:48 +02:00
Wouter Vermeer
2b5f28d8f1 added global static files + templates folders. updated .env variables to be lowercase as my styler auto-updated it to be lowercase. 2026-04-30 17:46:52 +02:00
Wouter Vermeer
a06026cb37 fixed nginx .conf.template as it is required to be called 'default.conf.template' to be loaded into the default. 2026-04-30 17:44:04 +02:00
Wouter Vermeer
5c132f5d37 fixed nginx .conf.template as it is required to be called 'default.conf.template' to be loaded into the default. 2026-04-30 17:43:39 +02:00
Wouter Vermeer
7db860a4eb added tailwindcss 2026-04-30 17:42:44 +02:00
Wouter Vermeer
6d6534a541 auto style changes 2026-04-30 17:42:06 +02:00
Wouter Vermeer
358bd4cbf2 reworded docker compose files to segregate responsibilites. Dev version no longer uses the nginx proxy to proxy, merely to be the static file server. Also dev version no longer used gunicorn as it was screwing up the live reload functionality and didn't provide any other benefit. 2026-04-30 17:41:21 +02:00
36 changed files with 336 additions and 78 deletions

View File

@@ -1,18 +1,36 @@
---
services: services:
web: web:
command: gunicorn --capture-output --enable-stdio-inheritance -b 0.0.0.0:8000 website.wsgi:application command: python manage.py runserver 0.0.0.0:8000
volumes: volumes: [./src:/src]
- ./src:/src
env_file: env_file:
- path: .env.template - path: .env.template
required: true required: true
- path: .env - path: .env
required: false required: false
environment:
DJANGO_RELOAD: true
DEBUG: true
ALLOWED_HOSTS: localhost,127.0.0.1
ports: [127.0.0.1:8000:8000]
db: db:
env_file: env_file:
- path: .env.template - path: .env.template
required: true required: true
- path: .env - path: .env
required: false required: false
proxy:
restart: unless-stopped
ports: [127.0.0.1:80:80]
environment: [NGINX_HOSTNAME=localhost, NGINX_PORT=80]
tailwind:
image: python:3.14-slim
working_dir: /src
command: >
sh -c "apt-get update && apt-get install -y curl &&
curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
-o /usr/local/bin/tailwindcss &&
chmod +x /usr/local/bin/tailwindcss &&
tailwindcss -i ./static/css/input.css -o ./static/css/output.css --watch"
volumes: [.:/src]
networks: [frontend]

View File

@@ -1,10 +1,25 @@
---
services: services:
web: web:
command: gunicorn website.wsgi:application
restart: unless-stopped
environment:
ALLOWED_HOSTS: ${NGINX_HOSTNAME}
DJANGO_SETTINGS_MODULE: ${DJANGO_SETTINGS_MODULE}
env_file: env_file:
- path: .env - path: .env
required: true required: true
db: db:
restart: unless-stopped
env_file: env_file:
- path: .env - path: .env
required: true required: true
adminer:
restart: unless-stopped
proxy:
restart: unless-stopped
ports: [80:80, 443:443]
environment:
- NGINX_HOSTNAME=${NGINX_HOSTNAME}
- NGINX_PORT=80
- NGINX_SSL_PORT=443

View File

@@ -1,14 +1,17 @@
---
services: services:
web: web:
command: python manage.py check --deploy; python -Wa manage.py test --noinput --parallel command: python manage.py check --deploy; python -Wa manage.py test --noinput
restart: "no" --parallel
environment:
DEBUG: false
DJANGO_SETTINGS_MODULE: website.settings.test
env_file: env_file:
- path: .env.template - path: .env.template
required: true required: true
db: db:
# Tmpfs keeps tests fast and isolated — no persistent volume needed
tmpfs: [/var/lib/postgresql/data]
env_file: env_file:
- path: .env.template - path: .env.template
required: true required: true

View File

@@ -4,8 +4,6 @@ NGINX_HOSTNAME=localhost
# Django # Django
DJANGO_SETTINGS_MODULE=website.settings DJANGO_SETTINGS_MODULE=website.settings
DJANGO_SECRET_KEY=CWHZCAZBNV57tDkwGHJwTUu3PCSnGG45 DJANGO_SECRET_KEY=CWHZCAZBNV57tDkwGHJwTUu3PCSnGG45
DEBUG=TRUE
#ALLOWED_HOSTS=localhost
# Database (PostgreSQL) # Database (PostgreSQL)
POSTGRES_USER=test_user POSTGRES_USER=test_user
@@ -17,4 +15,4 @@ POSTGRES_DB=test_db
# Gunicorn # Gunicorn
GUNICORN_WORKERS=3 GUNICORN_WORKERS=3
GUNICORN_TIMEOUT=120 GUNICORN_TIMEOUT=120

View File

@@ -1,38 +1,30 @@
---
name: Deploy to production name: Deploy to production
run-name: deploy-${{ gitea.actor }} run-name: deploy-${{ gitea.actor }}
on: on:
push: push:
branches: branches: [main]
- main
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup SSH - name: Setup SSH
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Deploy - name: Deploy
run: | run: |-
ssh -i ~/.ssh/id_rsa ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF' ssh -i ~/.ssh/id_rsa ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF'
cd ~/Quatsh-Website cd ~/Quatsh-Website
echo "Pulling latest code..." echo "Pulling latest code..."
git pull origin main git pull origin main
echo "Building containers..." echo "Building containers..."
make prod make prod
echo "Running Django deploy check" echo "Running Django deploy check"
docker compose run --rm web python manage.py check --deploy docker compose run --rm web python manage.py check --deploy
echo "Deployment complete." echo "Deployment complete."
EOF EOF

View File

@@ -1,18 +1,16 @@
---
name: Gitea Test. name: Gitea Test.
run-name: ${{ gitea.actor }} run-name: ${{ gitea.actor }}
on: on:
push: push:
branches: branches: [main, pre-prod]
- main
- pre-prod
pull_request: pull_request:
jobs: jobs:
tests: tests:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: lint
run: make lint
- name: test - name: test
run: make test run: make test

3
.gitignore vendored
View File

@@ -178,4 +178,5 @@ cython_debug/
# gunicon webserver # gunicon webserver
gunicorn.ctl gunicorn.ctl
# tailwind stuff
output.css

View File

@@ -1,4 +1,4 @@
FROM python:3.14-alpine FROM python:3.14-slim
ENV PYTHONDONTWRITEBYTECODE=1 \ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 PYTHONUNBUFFERED=1
@@ -12,4 +12,11 @@ RUN pip install --upgrade pip && \
COPY gunicorn.conf.py /src/ COPY gunicorn.conf.py /src/
COPY ./src/ /src/ COPY ./src/ /src/
RUN apt-get update && apt-get install -y --no-install-recommends curl && \
curl -sL https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 -o /usr/local/bin/tailwindcss && \
chmod +x /usr/local/bin/tailwindcss && \
apt-get remove -y curl && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
RUN tailwindcss build -i ./static/css/input.css -o ./static/css/output.css --minify
CMD ["gunicorn", "website.wsgi:application"] CMD ["gunicorn", "website.wsgi:application"]

View File

@@ -1,14 +1,14 @@
.SHELLFLAGS := -ec .SHELLFLAGS := -ec
prod: prod:
docker compose down docker compose --env-file .env -f ./compose.yaml -f ./.docker-compose-files/compose.prod.yaml down
docker compose --env-file .env -f ./compose.yaml -f ./.docker-compose-files/compose.prod.yaml up -d --build docker compose --env-file .env -f ./compose.yaml -f ./.docker-compose-files/compose.prod.yaml up -d --build
docker compose exec web python manage.py collectstatic --noinput docker compose exec web python manage.py collectstatic --noinput
docker compose exec web python manage.py check --deploy docker compose exec web python manage.py check --deploy
docker compose exec web python manage.py migrate docker compose exec web python manage.py migrate
dev: dev:
docker compose down docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml down
docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up --build -d docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up --build -d
docker compose exec web python manage.py collectstatic --noinput docker compose exec web python manage.py collectstatic --noinput
docker compose exec -it web sh docker compose exec -it web sh

View File

@@ -43,6 +43,8 @@ To run the website 3 options have been provided
For development purposes only as the src folder has been mounted in the container to allow for the making of changes without rebuilding the entire image. For development purposes only as the src folder has been mounted in the container to allow for the making of changes without rebuilding the entire image.
Properly utilising this also requires the DEBUG environment variable to be set to TRUE. Properly utilising this also requires the DEBUG environment variable to be set to TRUE.
Setup to allow live-reloading without manual intervention after normal file changes (i.e. updates to css, html and python functions).
```shell ```shell
make dev make dev
``` ```

View File

@@ -2,16 +2,9 @@
services: services:
web: web:
build: . build: .
command: gunicorn website.wsgi:application
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
environment:
ALLOWED_HOSTS: ${NGINX_HOSTNAME}
DJANGO_SETTINGS_MODULE: ${DJANGO_SETTINGS_MODULE}
# VIRTUAL_HOST: localhost
# VIRTUAL_PORT: 8000
restart: unless-stopped
volumes: [static_volume:/app/static, media_volume:/app/media] volumes: [static_volume:/app/static, media_volume:/app/media]
networks: [frontend, backend] networks: [frontend, backend]
db: db:
@@ -21,32 +14,24 @@ services:
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes: [postgres_data:/var/lib/postgresql] volumes: [postgres_data:/var/lib/postgresql]
restart: unless-stopped
healthcheck: healthcheck:
test: [CMD-SHELL, 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DBNAME}'] test: [CMD-SHELL, 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DBNAME}']
interval: 5s interval: 5s
retries: 5 retries: 5
networks: [backend] networks: [backend]
adminer:
image: adminer
depends_on: [db]
restart: always
ports: [127.0.0.1:8080:8080]
networks: [backend]
proxy: proxy:
image: nginx:stable image: nginx:stable
volumes: volumes:
- ./.nginx/.templates:/etc/nginx/templates - ./.nginx/.templates:/etc/nginx/templates
- static_volume:/app/static:ro - static_volume:/app/static:ro
- media_volume:/app/media:ro - media_volume:/app/media:ro
restart: unless-stopped
ports: [80:80, 443:443]
environment:
- NGINX_HOSTNAME=${NGINX_HOSTNAME}
- NGINX_PORT=80
- NGINX_SSL_PORT=443
depends_on: [web] depends_on: [web]
networks: [frontend] networks: [frontend]
adminer:
image: adminer
depends_on: [db]
ports: [127.0.0.1:8080:8080]
networks: [backend]
networks: networks:
frontend: frontend:
backend: backend:

View File

@@ -2,23 +2,59 @@
This document contains the wanted feature list and their current state. This document contains the wanted feature list and their current state.
## Basic Pages ## Basic Templates
- [] Nav-bar ~ Adjust based on permission status
- [] Low-bar ~ KVK etc.
- [] Basic page layout
-[] Homepage ## Pages
-[] Boards
-[] Committee page
-[] Contact page
-[] Donator page/Friends of Quatsh
-[] Membership page
## Main Features ### Must
-[] Signup form with email SMTP link. - [] Homepage
-[] Gallery - [] Signups
-[] Login page - [] Contact
- [] Contribution-Cost
### Should
- [] Login page
- [] Gallery
- [] Boards
### Could
- [] Committee page
- [] Donator page/Friends of Quatsh
## Features
- [] Signup form with email SMTP link.
- [] Gallery
- [] Login page
## Security
- [] SSL implementation
- [] ACME SSL certificate
## Extra's ## Extra's
-[] Allow google-workspace login with SSO? - [] Allow google-workspace login with SSO?
-[] Add Redis for Caching - [] Add Redis for Caching
-[] Setup SMTP with automatic switching to in-mem email saving OR print to stdout when in DEBUG mode. - [] Add [Celery](https://docs.celeryq.dev/en/stable/index.html#) for async background-[task](https://docs.djangoproject.com/en/6.0/topics/tasks/) completion.
- [] Setup SMTP with automatic switching to in-mem email saving OR print to stdout when in DEBUG mode.
- [] Split-Storage setup for authenticated-only file access, such as private gallery pictures.
## Priority List
- [] General layout template
- [] Nav-bar
- [] Homepage
- [] Lower-bar ~ KVK
- [] Signups page
- [] Calender (Google calender)
- [] Gallery
- [] CCP page
- [] Contact page
- [] Boards
- [] Committee page
- [] Donator page/Friends of Quatsh

View File

@@ -20,3 +20,12 @@ After running this command a Django Migration has to be run to remake the tables
``` shell ``` shell
docker exec quatsh-website-web-1 python manage.py migrate docker exec quatsh-website-web-1 python manage.py migrate
``` ```
## Make - errors
If you see an error looking as follows docker isn't actually running.
```
PS C:\*\Quatsh-Website> docker compose ls
error during connect: Get "http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/v1.50/containers/json?filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%22%3Atrue%7D%7D": open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.
```

0
src/core/__init__.py Normal file
View File

3
src/core/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
src/core/apps.py Normal file
View File

@@ -0,0 +1,5 @@
from django.apps import AppConfig
class CoreConfig(AppConfig):
name = 'core'

View File

3
src/core/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome</h1>
<div>
{% include "components/carousel.html" with carousel_id="hero" carousel_images=carousel_images %}
</div>
{% endblock %}

3
src/core/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

9
src/core/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from . import views
app_name = "core"
urlpatterns = [
path("", views.index, name="index"),
]

10
src/core/views.py Normal file
View File

@@ -0,0 +1,10 @@
from django.shortcuts import render
from django.templatetags.static import static
def index(request):
return render(
request,
"core/index.html",
{"carousel_images": [static("/core/img/5x5-2023-11-16-at-14.56.56-1.jpeg")]},
)

View File

@@ -0,0 +1,4 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Home{% endblock %}
{% block content %}<h1>Welcome</h1>{% endblock %}

9
src/gallery/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from . import views
app_name = "gallery"
urlpatterns = [
path("", views.index, name="index"),
]

View File

@@ -1,3 +1,5 @@
from django.shortcuts import render from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, "gallery/index.html")

View File

@@ -2,6 +2,8 @@ from django.urls import path
from . import views from . import views
app_name = "polls"
urlpatterns = [ urlpatterns = [
# ex: /polls/ # ex: /polls/
path("", views.index, name="index"), path("", views.index, name="index"),

1
src/static/css/input.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss"

68
src/static/js/carousel.js Normal file
View File

@@ -0,0 +1,68 @@
function initCarousel(id) {
document.addEventListener("DOMContentLoaded", function () {
const track = document.getElementById(id);
const originalSlides = Array.from(track.children);
const total = originalSlides.length;
if (total <= 1) {
return;
}
const firstClone = originalSlides[0].cloneNode(true);
const lastClone = originalSlides[total - 1].cloneNode(true);
track.appendChild(firstClone);
track.insertBefore(lastClone, originalSlides[0]);
let current = 1;
let isTransitioning = false;
track.style.transform = `translateX(-${current * 100}%)`;
const dots = document.querySelectorAll(`.${id}_dot`);
function updateDots(index) {
const realIndex = (index - 1 + total) % total;
dots.forEach((d, i) => {
d.classList.toggle("opacity-100", i === realIndex);
d.classList.toggle("opacity-50", i !== realIndex);
});
}
function goTo(index) {
if (isTransitioning) return;
isTransitioning = true;
track.style.transition = "transform 500ms ease-in-out";
current = index;
track.style.transform = `translateX(-${current * 100}%)`;
updateDots(current);
}
function next() {
goTo(current + 1);
}
function prev() {
goTo(current - 1);
}
track.addEventListener("transitionend", function () {
if (current === 0) {
track.style.transition = "none";
current = total;
track.style.transform = `translateX(-${current * 100}%)`;
}
if (current === total + 1) {
track.style.transition = "none";
current = 1;
track.style.transform = `translateX(-${current * 100}%)`;
}
isTransitioning = false;
});
setInterval(next, 5000);
updateDots(current);
window[`${id}_goTo`] = (i) => goTo(i + 1);
window[`${id}_next`] = next;
window[`${id}_prev`] = prev;
});
}

18
src/templates/base.html Normal file
View File

@@ -0,0 +1,18 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
{% block title %}My Site{% endblock %}
</title>
<link rel="stylesheet" href="{% static 'css/output.css' %}">
</head>
<body>
{% include "components/topbar.html" %}
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>

View File

@@ -0,0 +1,28 @@
{% load static %}
<div class="relative w-full overflow-hidden">
<div id="{{ carousel_id }}" class="flex w-full">
{% for image in carousel_images %}
<div class="w-full flex-shrink-0">
<img src="{{ image }}" class="w-full object-cover">
</div>
{% endfor %}
</div>
{% if carousel_images|length > 1 %}
<button onclick="{{ carousel_id }}_prev()"
class="absolute left-2 top-1/2 -translate-y-1/2 bg-black/50 text-white px-3 py-1 rounded-full">
&#8592;
</button>
<button onclick="{{ carousel_id }}_next()"
class="absolute right-2 top-1/2 -translate-y-1/2 bg-black/50 text-white px-3 py-1 rounded-full">
&#8594;
</button>
<div class="absolute bottom-2 w-full flex justify-center gap-2">
{% for image in carousel_images %}
<span class="{{ carousel_id }}_dot w-2 h-2 rounded-full bg-white opacity-50 cursor-pointer"
onclick="{{ carousel_id }}_goTo({{ forloop.counter0 }})"></span>
{% endfor %}
</div>
{% endif %}
</div>
<script src="{% static 'js/carousel.js' %}"></script>
<script>initCarousel('{{ carousel_id }}');</script>

View File

@@ -0,0 +1,8 @@
<nav>
<ul>
<li><a href="{% url 'core:index' %}">Home</a></li>
<li><a href="{% url 'polls:index' %}">Polls</a></li>
<li><a href="{% url 'gallery:index' %}">Gallery</a></li>
</ul>
<!-- rest of your topbar -->
</nav>

View File

@@ -10,8 +10,8 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/6.0/ref/settings/ https://docs.djangoproject.com/en/6.0/ref/settings/
""" """
from pathlib import Path
import os import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@@ -24,7 +24,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"] SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv("DEBUG") == "TRUE" DEBUG = os.getenv("DEBUG", "false") == "true"
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "127.0.0.1").split(",") ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "127.0.0.1").split(",")
@@ -34,6 +34,8 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
INSTALLED_APPS = [ INSTALLED_APPS = [
"polls.apps.PollsConfig", "polls.apps.PollsConfig",
"core.apps.CoreConfig",
"gallery.apps.GalleryConfig",
"django.contrib.admin", "django.contrib.admin",
"django.contrib.auth", "django.contrib.auth",
"django.contrib.contenttypes", "django.contrib.contenttypes",
@@ -53,7 +55,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
] ]
if os.getenv("DJANGO_RELOAD", "False") == "True": if os.getenv("DJANGO_RELOAD", "false") == "true":
INSTALLED_APPS.append("django_browser_reload") INSTALLED_APPS.append("django_browser_reload")
INSTALLED_APPS.append("django_watchfiles") INSTALLED_APPS.append("django_watchfiles")
MIDDLEWARE.append("django_browser_reload.middleware.BrowserReloadMiddleware") MIDDLEWARE.append("django_browser_reload.middleware.BrowserReloadMiddleware")
@@ -63,7 +65,7 @@ ROOT_URLCONF = "website.urls"
TEMPLATES = [ TEMPLATES = [
{ {
"BACKEND": "django.template.backends.django.DjangoTemplates", "BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [], "DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True, "APP_DIRS": True,
"OPTIONS": { "OPTIONS": {
"context_processors": [ "context_processors": [
@@ -129,3 +131,7 @@ USE_TZ = True
STATIC_ROOT = "/app/static/" STATIC_ROOT = "/app/static/"
STATIC_URL = "static/" STATIC_URL = "static/"
STATICFILES_DIRS = [
BASE_DIR / "static",
]

View File

@@ -21,10 +21,12 @@ from django.contrib import admin
from django.urls import include, path from django.urls import include, path
urlpatterns = [ urlpatterns = [
path("", include("core.urls")),
path("polls/", include("polls.urls")), path("polls/", include("polls.urls")),
path("gallery/", include("gallery.urls")),
path("admin/doc/", include("django.contrib.admindocs.urls")), path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
] ]
if os.getenv("DJANGO_RELOAD", "False") == "True": if os.getenv("DJANGO_RELOAD", "false") == "true":
urlpatterns.append(path("__reload__/", include("django_browser_reload.urls"))) urlpatterns.append(path("__reload__/", include("django_browser_reload.urls")))