diff --git a/baseball_organisator/__pycache__/middleware.cpython-313.pyc b/baseball_organisator/__pycache__/middleware.cpython-313.pyc
new file mode 100644
index 0000000..3a7fd3f
Binary files /dev/null and b/baseball_organisator/__pycache__/middleware.cpython-313.pyc differ
diff --git a/baseball_organisator/__pycache__/settings.cpython-313.pyc b/baseball_organisator/__pycache__/settings.cpython-313.pyc
index fb1f5f9..a362f9d 100644
Binary files a/baseball_organisator/__pycache__/settings.cpython-313.pyc and b/baseball_organisator/__pycache__/settings.cpython-313.pyc differ
diff --git a/baseball_organisator/middleware.py b/baseball_organisator/middleware.py
new file mode 100644
index 0000000..5348f35
--- /dev/null
+++ b/baseball_organisator/middleware.py
@@ -0,0 +1,14 @@
+import pytz
+from django.utils import timezone
+
+class TimezoneMiddleware:
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ tzname = 'Europe/Berlin'
+ if tzname:
+ timezone.activate(pytz.timezone(tzname))
+ else:
+ timezone.deactivate()
+ return self.get_response(request)
diff --git a/baseball_organisator/settings.py b/baseball_organisator/settings.py
index d38116e..f18ca0f 100644
--- a/baseball_organisator/settings.py
+++ b/baseball_organisator/settings.py
@@ -46,6 +46,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
+ 'baseball_organisator.middleware.TimezoneMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
diff --git a/calendars/__pycache__/forms.cpython-313.pyc b/calendars/__pycache__/forms.cpython-313.pyc
index 7c42813..3152b2e 100644
Binary files a/calendars/__pycache__/forms.cpython-313.pyc and b/calendars/__pycache__/forms.cpython-313.pyc differ
diff --git a/calendars/__pycache__/models.cpython-313.pyc b/calendars/__pycache__/models.cpython-313.pyc
index b6336c4..6935a52 100644
Binary files a/calendars/__pycache__/models.cpython-313.pyc and b/calendars/__pycache__/models.cpython-313.pyc differ
diff --git a/calendars/__pycache__/urls.cpython-313.pyc b/calendars/__pycache__/urls.cpython-313.pyc
index c81d853..dccd8bd 100644
Binary files a/calendars/__pycache__/urls.cpython-313.pyc and b/calendars/__pycache__/urls.cpython-313.pyc differ
diff --git a/calendars/__pycache__/views.cpython-313.pyc b/calendars/__pycache__/views.cpython-313.pyc
index 432848a..bb6c707 100644
Binary files a/calendars/__pycache__/views.cpython-313.pyc and b/calendars/__pycache__/views.cpython-313.pyc differ
diff --git a/calendars/forms.py b/calendars/forms.py
index 790a394..092d222 100644
--- a/calendars/forms.py
+++ b/calendars/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from .models import Event, Training, Game
+from .models import Event, Training, Game, GameResult
from clubs.models import Team
class EventForm(forms.ModelForm):
@@ -32,3 +32,23 @@ class OpenGameForm(forms.Form):
club = kwargs.pop('club')
super().__init__(*args, **kwargs)
self.fields['teams'].queryset = Team.objects.filter(club=club)
+
+class GameResultForm(forms.ModelForm):
+ class Meta:
+ model = GameResult
+ fields = []
+
+ def __init__(self, *args, **kwargs):
+ game = kwargs.pop('game')
+ super().__init__(*args, **kwargs)
+
+ if game.is_home_game:
+ home_team = game.team.name
+ guest_team = game.opponent
+ else:
+ home_team = game.opponent
+ guest_team = game.team.name
+
+ for i in range(1, game.number_of_innings + 1):
+ self.fields[f'inning_{i}_home'] = forms.IntegerField(label=f'Inning {i} ({home_team})', required=False)
+ self.fields[f'inning_{i}_guest'] = forms.IntegerField(label=f'Inning {i} ({guest_team})', required=False)
diff --git a/calendars/migrations/0005_game_number_of_innings_and_more.py b/calendars/migrations/0005_game_number_of_innings_and_more.py
new file mode 100644
index 0000000..099b154
--- /dev/null
+++ b/calendars/migrations/0005_game_number_of_innings_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 5.2.6 on 2025-10-02 12:14
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('calendars', '0004_game_is_home_game'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='game',
+ name='number_of_innings',
+ field=models.PositiveIntegerField(default=9),
+ ),
+ migrations.AlterField(
+ model_name='gameresult',
+ name='inning_results',
+ field=models.JSONField(default=dict),
+ ),
+ ]
diff --git a/calendars/migrations/__pycache__/0005_game_number_of_innings_and_more.cpython-313.pyc b/calendars/migrations/__pycache__/0005_game_number_of_innings_and_more.cpython-313.pyc
new file mode 100644
index 0000000..8147ddc
Binary files /dev/null and b/calendars/migrations/__pycache__/0005_game_number_of_innings_and_more.cpython-313.pyc differ
diff --git a/calendars/models.py b/calendars/models.py
index 16ebcd4..5ce1ae0 100644
--- a/calendars/models.py
+++ b/calendars/models.py
@@ -28,12 +28,12 @@ class Game(Event):
season = models.CharField(max_length=255, blank=True)
min_players = models.PositiveIntegerField(default=9)
is_home_game = models.BooleanField(default=True)
+ number_of_innings = models.PositiveIntegerField(default=9)
opened_for_teams = models.ManyToManyField('clubs.Team', related_name='opened_games', blank=True)
class GameResult(models.Model):
game = models.OneToOneField(Game, on_delete=models.CASCADE, related_name='result')
- # A simple way to store inning results as a string. A more complex solution could use a JSONField or separate Inning model.
- inning_results = models.CharField(max_length=255, help_text="Comma-separated scores per inning, e.g., '1-0,0-2,3-1'")
+ inning_results = models.JSONField(default=dict)
def __str__(self):
return f"Result for {self.game}"
diff --git a/calendars/templates/calendars/record_results.html b/calendars/templates/calendars/record_results.html
new file mode 100644
index 0000000..6f2a46c
--- /dev/null
+++ b/calendars/templates/calendars/record_results.html
@@ -0,0 +1,55 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/calendars/urls.py b/calendars/urls.py
index f87647a..2e3762e 100644
--- a/calendars/urls.py
+++ b/calendars/urls.py
@@ -10,4 +10,5 @@ urlpatterns = [
path('event//delete/', views.EventDeleteView.as_view(), name='event-delete'),
path('participation////', views.manage_participation, name='manage-participation'),
path('game//open/', views.open_game, name='open-game'),
+ path('game//results/', views.record_results, name='record-results'),
]
diff --git a/calendars/views.py b/calendars/views.py
index e7225ff..ae8bd13 100644
--- a/calendars/views.py
+++ b/calendars/views.py
@@ -3,8 +3,8 @@ from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
-from .models import Event, Training, Game, EventParticipation
-from .forms import EventForm, TrainingForm, GameForm, OpenGameForm
+from .models import Event, Training, Game, EventParticipation, GameResult
+from .forms import EventForm, TrainingForm, GameForm, OpenGameForm, GameResultForm
from accounts.models import CustomUser # Import CustomUser for manage_participation view
from django.utils import timezone
import datetime
@@ -142,4 +142,39 @@ def open_game(request, game_id):
else:
form = OpenGameForm(club=club)
- return render(request, 'calendars/open_game.html', {'form': form, 'game': game})
\ No newline at end of file
+ return render(request, 'calendars/open_game.html', {'form': form, 'game': game})
+
+@login_required
+def record_results(request, game_id):
+ game = get_object_or_404(Game, id=game_id)
+ game_result, created = GameResult.objects.get_or_create(game=game)
+
+ if request.method == 'POST':
+ form = GameResultForm(request.POST, game=game, instance=game_result)
+ if form.is_valid():
+ inning_results = {}
+ for i in range(1, game.number_of_innings + 1):
+ inning_results[f'inning_{i}'] = {
+ 'home': form.cleaned_data.get(f'inning_{i}_home'),
+ 'guest': form.cleaned_data.get(f'inning_{i}_guest'),
+ }
+ game_result.inning_results = inning_results
+ game_result.save()
+ return redirect('dashboard')
+ else:
+ initial_data = {}
+ if game_result.inning_results:
+ for inning, scores in game_result.inning_results.items():
+ initial_data[f'{inning}_home'] = scores.get('home')
+ initial_data[f'{inning}_guest'] = scores.get('guest')
+ form = GameResultForm(game=game, instance=game_result, initial=initial_data)
+
+ form_fields_by_inning = []
+ for i in range(1, game.number_of_innings + 1):
+ form_fields_by_inning.append({
+ 'inning': i,
+ 'home': form[f'inning_{i}_home'],
+ 'guest': form[f'inning_{i}_guest'],
+ })
+
+ return render(request, 'calendars/record_results.html', {'form': form, 'game': game, 'form_fields_by_inning': form_fields_by_inning})
\ No newline at end of file
diff --git a/dashboard/__pycache__/views.cpython-313.pyc b/dashboard/__pycache__/views.cpython-313.pyc
index 572cd02..dd92471 100644
Binary files a/dashboard/__pycache__/views.cpython-313.pyc and b/dashboard/__pycache__/views.cpython-313.pyc differ
diff --git a/dashboard/templates/dashboard/dashboard.html b/dashboard/templates/dashboard/dashboard.html
index b464f9d..393e8ba 100644
--- a/dashboard/templates/dashboard/dashboard.html
+++ b/dashboard/templates/dashboard/dashboard.html
@@ -53,7 +53,10 @@
{% if user == item.event.team.head_coach or user in item.event.team.assistant_coaches.all %}
Edit
Delete
-
+
+ {% if item.event.game %}
+ Record Results
+ {% endif %}
{% if item.event.game and item.days_until_event >= 0 and item.days_until_event < 7 and item.accepted_count < item.required_players and item.event.team.club.teams.count > 1 %}
Open Game
{% endif %}
@@ -137,4 +140,30 @@
{% endif %}
{% endfor %}
{% endif %}
+{% endblock %}
+
+{% block javascript %}
+
{% endblock %}
\ No newline at end of file
diff --git a/dashboard/views.py b/dashboard/views.py
index 95a08c4..32fcebd 100644
--- a/dashboard/views.py
+++ b/dashboard/views.py
@@ -46,13 +46,15 @@ def dashboard(request):
player_participations.append({'player': player, 'status': status})
days_until_event = (event.start_time - timezone.now()).days
+ local_start_time = timezone.localtime(event.start_time)
events_with_participation.append({
'event': event,
'accepted_count': accepted_count,
'required_players': required_players,
'player_participations': player_participations,
- 'days_until_event': days_until_event
+ 'days_until_event': days_until_event,
+ 'local_start_time_iso': local_start_time.isoformat()
})
# Get children's events
diff --git a/db.sqlite3 b/db.sqlite3
index ada3856..95ffdda 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/docs/traceback/trace10.log b/docs/traceback/trace10.log
new file mode 100644
index 0000000..941bd7a
--- /dev/null
+++ b/docs/traceback/trace10.log
@@ -0,0 +1,36 @@
+Hiding button for event starting at
+
+DOM fully loaded and parsed 127.0.0.1:8000:720:13
+GET
+http://127.0.0.1:8000/favicon.ico
+[HTTP/1.1 404 Not Found 0ms]
+
+Found buttons: 3 127.0.0.1:8000:722:13
+Current client time:
+Date Thu Oct 02 2025 15:02:08 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:724:13
+Button start time string: 2025-10-02T13:10:00+00:00 127.0.0.1:8000:728:17
+Button start time object:
+Date Thu Oct 02 2025 15:10:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:730:17
+Hiding button for event starting at
+Date Thu Oct 02 2025 15:10:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:736:21
+Button start time string: 2025-10-05T19:00:00+00:00 127.0.0.1:8000:728:17
+Button start time object:
+Date Sun Oct 05 2025 21:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:730:17
+Hiding button for event starting at
+Date Sun Oct 05 2025 21:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:736:21
+Button start time string: 2025-10-06T17:47:00+00:00 127.0.0.1:8000:728:17
+Button start time object:
+Date Mon Oct 06 2025 19:47:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:730:17
+Hiding button for event starting at
+Date Mon Oct 06 2025 19:47:00 GMT+0200 (Mitteleuropäische Sommerzeit)
+127.0.0.1:8000:736:21
+Source-Map-Fehler: request failed with status 404
+Ressourcen-Adresse: http://127.0.0.1:8000/static/js/bootstrap.bundle.min.js
+Source-Map-Adresse: bootstrap.bundle.min.js.map
+
diff --git a/docs/traceback/trace11.log b/docs/traceback/trace11.log
new file mode 100644
index 0000000..e7bb75c
--- /dev/null
+++ b/docs/traceback/trace11.log
@@ -0,0 +1,82 @@
+[02/Oct/2025 13:07:49] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:07:52] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:07:53] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:07:53] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:07:53] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:08:01] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:08:01] "GET /static/js/bootstrap.bundle.min.js.map HTTP/1.1" 404 1904
+[02/Oct/2025 13:08:13] "GET /static/js/bootstrap.bundle.min.js.map HTTP/1.1" 404 1904
+[02/Oct/2025 13:08:15] "GET / HTTP/1.1" 200 27859
+[02/Oct/2025 13:08:15] "GET /static/js/bootstrap.bundle.min.js.map HTTP/1.1" 404 1904
+/home/mnagel/Projekte/baseball_organisator/baseball_organisator/settings.py changed, reloading.
+Watching for file changes with StatReloader
+Performing system checks...
+
+System check identified no issues (0 silenced).
+Exception in thread django-main-thread:
+Traceback (most recent call last):
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/servers/basehttp.py", line 48, in get_internal_wsgi_application
+ return import_string(app_path)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/module_loading.py", line 30, in import_string
+ return cached_import(module_path, class_name)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/module_loading.py", line 15, in cached_import
+ module = import_module(module_path)
+ File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module
+ return _bootstrap._gcd_import(name[level:], package, level)
+ ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "", line 1387, in _gcd_import
+ File "", line 1360, in _find_and_load
+ File "", line 1331, in _find_and_load_unlocked
+ File "", line 935, in _load_unlocked
+ File "", line 1026, in exec_module
+ File "", line 488, in _call_with_frames_removed
+ File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/wsgi.py", line 16, in
+ application = get_wsgi_application()
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/wsgi.py", line 13, in get_wsgi_application
+ return WSGIHandler()
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/handlers/wsgi.py", line 118, in __init__
+ self.load_middleware()
+ ~~~~~~~~~~~~~~~~~~~~^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/handlers/base.py", line 40, in load_middleware
+ middleware = import_string(middleware_path)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/module_loading.py", line 30, in import_string
+ return cached_import(module_path, class_name)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/module_loading.py", line 15, in cached_import
+ module = import_module(module_path)
+ File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module
+ return _bootstrap._gcd_import(name[level:], package, level)
+ ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "", line 1387, in _gcd_import
+ File "", line 1360, in _find_and_load
+ File "", line 1331, in _find_and_load_unlocked
+ File "", line 935, in _load_unlocked
+ File "", line 1026, in exec_module
+ File "", line 488, in _call_with_frames_removed
+ File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/middleware.py", line 1, in
+ import pytz
+ModuleNotFoundError: No module named 'pytz'
+
+The above exception was the direct cause of the following exception:
+
+Traceback (most recent call last):
+ File "/usr/lib64/python3.13/threading.py", line 1043, in _bootstrap_inner
+ self.run()
+ ~~~~~~~~^^
+ File "/usr/lib64/python3.13/threading.py", line 994, in run
+ self._target(*self._args, **self._kwargs)
+ ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/autoreload.py", line 64, in wrapper
+ fn(*args, **kwargs)
+ ~~^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/commands/runserver.py", line 143, in inner_run
+ handler = self.get_handler(*args, **options)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/contrib/staticfiles/management/commands/runserver.py", line 31, in get_handler
+ handler = super().get_handler(*args, **options)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/commands/runserver.py", line 73, in get_handler
+ return get_internal_wsgi_application()
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/servers/basehttp.py", line 50, in get_internal_wsgi_application
+ raise ImproperlyConfigured(
+ ...<2 lines>...
+ ) from err
+django.core.exceptions.ImproperlyConfigured: WSGI application 'baseball_organisator.wsgi.application' could not be loaded; Error importing module.
+
diff --git a/docs/traceback/trace9.log b/docs/traceback/trace9.log
new file mode 100644
index 0000000..116922d
--- /dev/null
+++ b/docs/traceback/trace9.log
@@ -0,0 +1,77 @@
+For more information on production servers see: https://docs.djangoproject.com/en/5.2/howto/deployment/
+/home/mnagel/Projekte/baseball_organisator/calendars/forms.py changed, reloading.
+Watching for file changes with StatReloader
+Performing system checks...
+
+Exception in thread django-main-thread:
+Traceback (most recent call last):
+ File "/usr/lib64/python3.13/threading.py", line 1043, in _bootstrap_inner
+ self.run()
+ ~~~~~~~~^^
+ File "/usr/lib64/python3.13/threading.py", line 994, in run
+ self._target(*self._args, **self._kwargs)
+ ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/autoreload.py", line 64, in wrapper
+ fn(*args, **kwargs)
+ ~~^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/commands/runserver.py", line 134, in inner_run
+ self.check(**check_kwargs)
+ ~~~~~~~~~~^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/base.py", line 492, in check
+ all_issues = checks.run_checks(
+ app_configs=app_configs,
+ ...<2 lines>...
+ databases=databases,
+ )
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/registry.py", line 89, in run_checks
+ new_errors = check(app_configs=app_configs, databases=databases)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 16, in check_url_config
+ return check_resolver(resolver)
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 26, in check_resolver
+ return check_method()
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 531, in check
+ for pattern in self.url_patterns:
+ ^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__
+ res = instance.__dict__[self.name] = self.func(instance)
+ ~~~~~~~~~^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 718, in url_patterns
+ patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
+ ^^^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__
+ res = instance.__dict__[self.name] = self.func(instance)
+ ~~~~~~~~~^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 711, in urlconf_module
+ return import_module(self.urlconf_name)
+ File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module
+ return _bootstrap._gcd_import(name[level:], package, level)
+ ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "", line 1387, in _gcd_import
+ File "", line 1360, in _find_and_load
+ File "", line 1331, in _find_and_load_unlocked
+ File "", line 935, in _load_unlocked
+ File "", line 1026, in exec_module
+ File "", line 488, in _call_with_frames_removed
+ File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/urls.py", line 25, in
+ path('calendars/', include('calendars.urls')),
+ ~~~~~~~^^^^^^^^^^^^^^^^^^
+ File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/conf.py", line 39, in include
+ urlconf_module = import_module(urlconf_module)
+ File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module
+ return _bootstrap._gcd_import(name[level:], package, level)
+ ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "", line 1387, in _gcd_import
+ File "", line 1360, in _find_and_load
+ File "", line 1331, in _find_and_load_unlocked
+ File "", line 935, in _load_unlocked
+ File "", line 1026, in exec_module
+ File "", line 488, in _call_with_frames_removed
+ File "/home/mnagel/Projekte/baseball_organisator/calendars/urls.py", line 2, in
+ from . import views
+ File "/home/mnagel/Projekte/baseball_organisator/calendars/views.py", line 7, in
+ from .forms import EventForm, TrainingForm, GameForm, OpenGameForm
+ File "/home/mnagel/Projekte/baseball_organisator/calendars/forms.py", line 1, in
+ class GameResultForm(forms.ModelForm):
+ ^^^^^
+NameError: name 'forms' is not defined. Did you mean: 'format'?
+
diff --git a/templates/base.html b/templates/base.html
index 8278537..4abc5c9 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -61,5 +61,6 @@
+ {% block javascript %}{% endblock %}