feat: Implementierung von Spielergebnissen, Heimspiel-Status und Zeitzonen-Fix
This commit is contained in:
parent
450d3597d2
commit
ec07bfc53b
BIN
baseball_organisator/__pycache__/middleware.cpython-313.pyc
Normal file
BIN
baseball_organisator/__pycache__/middleware.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
14
baseball_organisator/middleware.py
Normal file
14
baseball_organisator/middleware.py
Normal file
@ -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)
|
||||||
@ -46,6 +46,7 @@ INSTALLED_APPS = [
|
|||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'baseball_organisator.middleware.TimezoneMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from .models import Event, Training, Game
|
from .models import Event, Training, Game, GameResult
|
||||||
from clubs.models import Team
|
from clubs.models import Team
|
||||||
|
|
||||||
class EventForm(forms.ModelForm):
|
class EventForm(forms.ModelForm):
|
||||||
@ -32,3 +32,23 @@ class OpenGameForm(forms.Form):
|
|||||||
club = kwargs.pop('club')
|
club = kwargs.pop('club')
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['teams'].queryset = Team.objects.filter(club=club)
|
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)
|
||||||
|
|||||||
23
calendars/migrations/0005_game_number_of_innings_and_more.py
Normal file
23
calendars/migrations/0005_game_number_of_innings_and_more.py
Normal file
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
@ -28,12 +28,12 @@ class Game(Event):
|
|||||||
season = models.CharField(max_length=255, blank=True)
|
season = models.CharField(max_length=255, blank=True)
|
||||||
min_players = models.PositiveIntegerField(default=9)
|
min_players = models.PositiveIntegerField(default=9)
|
||||||
is_home_game = models.BooleanField(default=True)
|
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)
|
opened_for_teams = models.ManyToManyField('clubs.Team', related_name='opened_games', blank=True)
|
||||||
|
|
||||||
class GameResult(models.Model):
|
class GameResult(models.Model):
|
||||||
game = models.OneToOneField(Game, on_delete=models.CASCADE, related_name='result')
|
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.JSONField(default=dict)
|
||||||
inning_results = models.CharField(max_length=255, help_text="Comma-separated scores per inning, e.g., '1-0,0-2,3-1'")
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Result for {self.game}"
|
return f"Result for {self.game}"
|
||||||
|
|||||||
55
calendars/templates/calendars/record_results.html
Normal file
55
calendars/templates/calendars/record_results.html
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2>Record Results for {{ game.title }}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Team</th>
|
||||||
|
{% for item in form_fields_by_inning %}
|
||||||
|
<th>{{ item.inning }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if game.is_home_game %}
|
||||||
|
{{ game.team.name }} (Home)
|
||||||
|
{% else %}
|
||||||
|
{{ game.opponent }} (Home)
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% for item in form_fields_by_inning %}
|
||||||
|
<td>{{ item.home }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if not game.is_home_game %}
|
||||||
|
{{ game.team.name }} (Guest)
|
||||||
|
{% else %}
|
||||||
|
{{ game.opponent }} (Guest)
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% for item in form_fields_by_inning %}
|
||||||
|
<td>{{ item.guest }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button type="submit" class="btn btn-primary">Save Results</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -10,4 +10,5 @@ urlpatterns = [
|
|||||||
path('event/<int:pk>/delete/', views.EventDeleteView.as_view(), name='event-delete'),
|
path('event/<int:pk>/delete/', views.EventDeleteView.as_view(), name='event-delete'),
|
||||||
path('participation/<int:child_id>/<int:event_id>/<str:status>/', views.manage_participation, name='manage-participation'),
|
path('participation/<int:child_id>/<int:event_id>/<str:status>/', views.manage_participation, name='manage-participation'),
|
||||||
path('game/<int:game_id>/open/', views.open_game, name='open-game'),
|
path('game/<int:game_id>/open/', views.open_game, name='open-game'),
|
||||||
|
path('game/<int:game_id>/results/', views.record_results, name='record-results'),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -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.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from .models import Event, Training, Game, EventParticipation
|
from .models import Event, Training, Game, EventParticipation, GameResult
|
||||||
from .forms import EventForm, TrainingForm, GameForm, OpenGameForm
|
from .forms import EventForm, TrainingForm, GameForm, OpenGameForm, GameResultForm
|
||||||
from accounts.models import CustomUser # Import CustomUser for manage_participation view
|
from accounts.models import CustomUser # Import CustomUser for manage_participation view
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import datetime
|
import datetime
|
||||||
@ -143,3 +143,38 @@ def open_game(request, game_id):
|
|||||||
form = OpenGameForm(club=club)
|
form = OpenGameForm(club=club)
|
||||||
|
|
||||||
return render(request, 'calendars/open_game.html', {'form': form, 'game': game})
|
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})
|
||||||
Binary file not shown.
@ -54,6 +54,9 @@
|
|||||||
<a href="{% url 'event-update' item.event.pk %}" class="btn btn-warning btn-sm">Edit</a>
|
<a href="{% url 'event-update' item.event.pk %}" class="btn btn-warning btn-sm">Edit</a>
|
||||||
<a href="{% url 'event-delete' item.event.pk %}" class="btn btn-danger btn-sm">Delete</a>
|
<a href="{% url 'event-delete' item.event.pk %}" class="btn btn-danger btn-sm">Delete</a>
|
||||||
|
|
||||||
|
{% if item.event.game %}
|
||||||
|
<a href="{% url 'record-results' item.event.game.id %}" class="btn btn-success btn-sm record-results-btn" style="display: none;" data-start-time="{{ item.local_start_time_iso }}">Record Results</a>
|
||||||
|
{% 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 %}
|
{% 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 %}
|
||||||
<a href="{% url 'open-game' item.event.game.id %}" class="btn btn-info btn-sm">Open Game</a>
|
<a href="{% url 'open-game' item.event.game.id %}" class="btn btn-info btn-sm">Open Game</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -138,3 +141,29 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascript %}
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
console.log('DOM fully loaded and parsed');
|
||||||
|
const recordButtons = document.querySelectorAll('.record-results-btn');
|
||||||
|
console.log('Found buttons:', recordButtons.length);
|
||||||
|
const now = new Date();
|
||||||
|
console.log('Current client time:', now);
|
||||||
|
|
||||||
|
recordButtons.forEach(button => {
|
||||||
|
const startTimeString = button.dataset.startTime;
|
||||||
|
console.log('Button start time string:', startTimeString);
|
||||||
|
const startTime = new Date(startTimeString);
|
||||||
|
console.log('Button start time object:', startTime);
|
||||||
|
|
||||||
|
if (now > startTime) {
|
||||||
|
console.log('Showing button for event starting at', startTime);
|
||||||
|
button.style.display = 'inline-block';
|
||||||
|
} else {
|
||||||
|
console.log('Hiding button for event starting at', startTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
@ -46,13 +46,15 @@ def dashboard(request):
|
|||||||
player_participations.append({'player': player, 'status': status})
|
player_participations.append({'player': player, 'status': status})
|
||||||
|
|
||||||
days_until_event = (event.start_time - timezone.now()).days
|
days_until_event = (event.start_time - timezone.now()).days
|
||||||
|
local_start_time = timezone.localtime(event.start_time)
|
||||||
|
|
||||||
events_with_participation.append({
|
events_with_participation.append({
|
||||||
'event': event,
|
'event': event,
|
||||||
'accepted_count': accepted_count,
|
'accepted_count': accepted_count,
|
||||||
'required_players': required_players,
|
'required_players': required_players,
|
||||||
'player_participations': player_participations,
|
'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
|
# Get children's events
|
||||||
|
|||||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
36
docs/traceback/trace10.log
Normal file
36
docs/traceback/trace10.log
Normal file
@ -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
|
||||||
|
|
||||||
82
docs/traceback/trace11.log
Normal file
82
docs/traceback/trace11.log
Normal file
@ -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 "<frozen importlib._bootstrap>", line 1387, in _gcd_import
|
||||||
|
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
|
||||||
|
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
|
||||||
|
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/wsgi.py", line 16, in <module>
|
||||||
|
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 "<frozen importlib._bootstrap>", line 1387, in _gcd_import
|
||||||
|
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
|
||||||
|
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
|
||||||
|
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/middleware.py", line 1, in <module>
|
||||||
|
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.
|
||||||
|
|
||||||
77
docs/traceback/trace9.log
Normal file
77
docs/traceback/trace9.log
Normal file
@ -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 "<frozen importlib._bootstrap>", line 1387, in _gcd_import
|
||||||
|
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
|
||||||
|
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
|
||||||
|
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/urls.py", line 25, in <module>
|
||||||
|
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 "<frozen importlib._bootstrap>", line 1387, in _gcd_import
|
||||||
|
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
|
||||||
|
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
|
||||||
|
File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
|
||||||
|
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/calendars/urls.py", line 2, in <module>
|
||||||
|
from . import views
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/calendars/views.py", line 7, in <module>
|
||||||
|
from .forms import EventForm, TrainingForm, GameForm, OpenGameForm
|
||||||
|
File "/home/mnagel/Projekte/baseball_organisator/calendars/forms.py", line 1, in <module>
|
||||||
|
class GameResultForm(forms.ModelForm):
|
||||||
|
^^^^^
|
||||||
|
NameError: name 'forms' is not defined. Did you mean: 'format'?
|
||||||
|
|
||||||
@ -61,5 +61,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
|
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
|
||||||
|
{% block javascript %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user