Thanks a lot for your help! At the very beginning it is unvaluable for me to get a second oppinion at some points.
I implemented all the features it should have. User authentication, SQLite database containing several models to represent students performance in exams, a javascript grading tool and the views are restricting to authenticated users.
But I’m trying for hours now to get “whitenoise” in django running. but i failed constantly to test in the deployment mode.
As long as i set DEBUG=True,
everything works just fine.
index.html DEBUG=True
as discibed here i run
python ./manage.py collectstatic
set DEBUG=False
python ./manage.py runserver
and it failes do load the images. Notably the CSS and JavaScript seems not to be a problem:
index.html DEBUG=False
The console prints the following errors:
Performing system checks...
System check identified some issues:
WARNINGS:
?: (staticfiles.W004) The directory 'C:\Users\Fungos\che119_score\che119_score\static' in the STATICFILES_DIRS setting does not exist.
System check identified 1 issue (0 silenced). :38:21] "GET /static/score/styles/styles.css HTTP/1.1" 200 4792
May 19, 2024 - 19:30:38 [19/May/2024 18
Django version 5.0.6, using settings 'che119_score.settings'
Starting development server at http://127.0.0.1:8000/ 79
Quit the server with CTRL-BREAK. 79
[19/May/2024 19:30:39] "GET / HTTP/1.1" 200 9337
[19/May/2024 19:30:39] "GET /static/score/styles/styles.css HTTP/1.1" 304 0
[19/May/2024 19:30:39] "GET /static/score/scripts/grading.js HTTP/1.1" 304 0
[19/May/2024 19:30:39] "GET /static/score/img/test6/1234_1.jpeg HTTP/1.1" 404 179
[19/May/2024 19:30:39] "GET /static/score/img/test6/1234_2.jpeg HTTP/1.1" 404 179
There might be an issue with the STATICFILES_DIRS settings, but i tried like anything, but without any success. Even when I force it to point at the location of the static folder it shows the exact same warning.
che119_score/settings.py
BASE_DIR = Path(__file__).resolve().parent.parent
DEBUG = True
ALLOWED_HOSTS = ["127.0.0.1", "localhost", '*']
INSTALLED_APPS = [
"whitenoise.runserver_nostatic", # suppresses djangos built in static file handling.
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"score",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'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',
]
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
File Structure
che119_score
| |----che119_score
| | |----__init__.py
| | |----asgi.py
| | |----settings.py
| | |----urls.py
| | |----wsgi.py
| |
| |----score
| | |----migrations (...database specific...)
| | |----static
| | |----score
| | | |----img
| | | | |----Test1
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test2
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test3
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test4
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test5
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test6
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | | |----Test7
| | | | | |----1234_1.jpeg
| | | | | |----1234_2.jpeg
| | | | |
| | | |
| | | |
| | | |
| | | |----scripts
| | | | |----grading.js
| | | |
| | | |----styles
| | | |----styles.css
| | |
| | |----templates
| | | |----score
| | | |----detail.html
| | | |----index.html
| | | |----layout.html
| | | |----login.html
| | |
| | | ----__init__.py
| | | ----admin.py
| | | ----apps.py
| | | ----models.py
| | | ----tests.py
| | | ----urls.py
| | | ----views.py
| |
| |----staticfiles
| | |----admin
| | | |----css
| | | |----img
| | | |----js
| | |
| | |----score
| | |----img
| | | |----Test1
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test2
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test3
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test4
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test5
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test6
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | | |----Test7
| | | | |----1234_1.jpeg
| | | | |----1234_2.jpeg
| | | |
| | |
| | |
| | |
| | |----scripts
| | | |----grading.js
| | |
| | |----styles
| | |----styles.css
| |
| |----db.sqlite3
| |----manage.py
|
|----venv
che119_score/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path("", include("score.urls")),
]
score/urls.py
urlpatterns = [
path('login/', views.log_in, name='log_in'),
path("logout/", views.log_out, name="log_out"),
path("detail/<int:exam_number>", views.detail, name="detail"),
path("", views.score, name="score"),
]
I took care to refere the images via the static tag, instead of harcoding urls:
index.html
{% extends 'score/layout.html' %}
{% load static %}
{% block body %}
<body>
<div class="scoreParticipation">
<h2>Mitarbeitspunkte</h2>
<h3>{{ participation.reached_points }} von {{ participation.max_points }} Punkten</h3>
</div>
{% for exam in exams %}
<div class="scoreTables">
<h2>Test {{ exam.exam_number }}</h2>
<h3>{{ exam.reached_points }} von {{ exam.max_points }} Punkten</h3>
<label>Thema: {{ exam.exam_topic }}</label>
<br>
<br>
<div>
{% block images %}
<div>
{% for exam_number in exam_numbers %}
{% if exam.exam_number|slugify == exam_number %}
{% with 'score/img/test'|add:exam_number|add:'/'|add:immatriculation_number|add:'_1.jpeg' as image_static %}
<a href="{% url 'detail' exam.exam_number %}"><img class="pages" style="width: 100px; height: 150px;" alt="Vorderseite Test {{ exam.exam_number }} von {{student.student_user.first_name}} {{student.student_user.last_name}}" src="{% static image_static %}"></a>
{% endwith %}
{% endif %}
{% endfor %}
{% for exam_number in exam_numbers %}
{% if exam.exam_number|slugify == exam_number %}
{% with 'score/img/test'|add:exam_number|add:'/'|add:immatriculation_number|add:'_2.jpeg' as image_static %}
<a href="{% url 'detail' exam.exam_number %}"><img class="pages" style="width: 100px; height: 150px;" alt="Rückseite Test {{ exam.exam_number }} von {{student.student_user.first_name}} {{student.student_user.last_name}}" src="{% static image_static %}"></a>
{% endwith %}
{% endif %}
{% endfor %}
</div>
{% endblock %}
</div>
</div>
{% endfor %}
</body>
{% endblock %}
views.py
...
def score(request):
if request.method == "GET":
if request.user.is_authenticated:
student = list(Student.objects.filter(student_user=request.user))[0]
exams = WrittenExam.objects.filter(student=student)
participation = list(Participation.objects.filter(student=student))[0]
exam_numbers = [str(exam.exam_number) for exam in exams]
context = {
"range": range(1,9),
"student": student,
"exams": exams,
"exam_numbers": exam_numbers,
"immatriculation_number": str(student.immatriculation_number),
"participation": participation,
"title": "CHE119 Beurteilungen SS2024"
}
return render(request, "score/index.html", context=context)
else:
context = {
"title": "Anmeldung Punktestand CHE119",
"range": range(1,9),
}
return render(request, "score/login.html", context=context)
else:
return Http404("Not available")
...
May not be the cleanest code, but it turned out to be by far more time consuming then expected to get this into deployment …
Maybe the problem is that i run the deployment settings on localhost? But the documentation of whitenoise explicitly states that one can assure it is working properly by running the commands i stated at the very top.
Thanks in advance for any comments or hints how i can get Django running with serving static files via whitenoise.