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 %} +
+
+
+
+

Record Results for {{ game.title }}

+
+
+
+ {% csrf_token %} + + + + + {% for item in form_fields_by_inning %} + + {% endfor %} + + + + + + {% for item in form_fields_by_inning %} + + {% endfor %} + + + + {% for item in form_fields_by_inning %} + + {% endfor %} + + +
Team{{ item.inning }}
+ {% if game.is_home_game %} + {{ game.team.name }} (Home) + {% else %} + {{ game.opponent }} (Home) + {% endif %} + {{ item.home }}
+ {% if not game.is_home_game %} + {{ game.team.name }} (Guest) + {% else %} + {{ game.opponent }} (Guest) + {% endif %} + {{ item.guest }}
+ +
+
+
+
+
+{% 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 %} + + {% 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 %}