feat: Implementierung von Phase 5 (Fortgeschrittene Funktionen und Backend) und Fehlerbehebungen
This commit is contained in:
parent
ea8439e616
commit
51bf727885
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/signals.cpython-313.pyc
Normal file
BIN
accounts/__pycache__/signals.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,13 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from .models import CustomUser, AbsencePeriod
|
||||
|
||||
# Register your models here.
|
||||
class CustomUserAdmin(UserAdmin):
|
||||
model = CustomUser
|
||||
list_display = ['email', 'username', 'team', 'is_staff']
|
||||
fieldsets = UserAdmin.fieldsets + (
|
||||
(None, {'fields': ('team',)}),
|
||||
)
|
||||
|
||||
admin.site.register(CustomUser, CustomUserAdmin)
|
||||
admin.site.register(AbsencePeriod)
|
||||
@ -1,6 +1,8 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AccountsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'accounts'
|
||||
|
||||
def ready(self):
|
||||
import accounts.signals
|
||||
@ -26,3 +26,12 @@ class CustomUserChangeForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = ('username', 'first_name', 'last_name', 'email', 'birth_date', 'player_number', 'team')
|
||||
|
||||
class PlayerCreationForm(forms.ModelForm):
|
||||
parent1_email = forms.EmailField(required=False)
|
||||
parent2_email = forms.EmailField(required=False)
|
||||
birth_date = forms.DateField(input_formats=['%d.%m.%Y'], widget=forms.DateInput(format='%d.%m.%Y'))
|
||||
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = ('username', 'first_name', 'last_name', 'email', 'birth_date', 'player_number', 'team')
|
||||
|
||||
24
accounts/migrations/0003_absenceperiod.py
Normal file
24
accounts/migrations/0003_absenceperiod.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-01 07:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0002_customuser_team'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AbsencePeriod',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('start_date', models.DateField()),
|
||||
('end_date', models.DateField()),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absence_periods', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -30,4 +30,9 @@ class InvitationCode(models.Model):
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
return self.code
|
||||
return self.code
|
||||
|
||||
class AbsencePeriod(models.Model):
|
||||
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='absence_periods')
|
||||
start_date = models.DateField()
|
||||
end_date = models.DateField()
|
||||
19
accounts/signals.py
Normal file
19
accounts/signals.py
Normal file
@ -0,0 +1,19 @@
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from .models import AbsencePeriod
|
||||
from calendars.models import Event, EventParticipation
|
||||
|
||||
@receiver(post_save, sender=AbsencePeriod)
|
||||
def handle_absence_period(sender, instance, **kwargs):
|
||||
user = instance.user
|
||||
events_in_period = Event.objects.filter(
|
||||
team=user.team,
|
||||
start_time__date__gte=instance.start_date,
|
||||
start_time__date__lte=instance.end_date
|
||||
)
|
||||
for event in events_in_period:
|
||||
EventParticipation.objects.update_or_create(
|
||||
user=user,
|
||||
event=event,
|
||||
defaults={'status': 'rejected'}
|
||||
)
|
||||
10
accounts/templates/accounts/logout.html
Normal file
10
accounts/templates/accounts/logout.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Logout</h2>
|
||||
<p>Are you sure you want to log out?</p>
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit">Log Out</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
10
accounts/templates/accounts/player_form.html
Normal file
10
accounts/templates/accounts/player_form.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Create Player</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Create Player</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@ -4,7 +4,14 @@
|
||||
<title>Baseball Organisator</title>
|
||||
</head>
|
||||
<body>
|
||||
{% if user.is_authenticated %}
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit">Log Out</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@ -5,7 +5,8 @@ from django.contrib.auth import views as auth_views
|
||||
urlpatterns = [
|
||||
path('invitation/', views.invitation_code_view, name='invitation_code'),
|
||||
path('register/', views.register_view, name='register'),
|
||||
path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'),
|
||||
path('login/', views.MyLoginView.as_view(template_name='accounts/login.html'), name='login'),
|
||||
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
|
||||
path('profile/', views.edit_profile, name='edit_profile'),
|
||||
path('player/add/', views.PlayerCreateView.as_view(), name='player-add'),
|
||||
]
|
||||
@ -1,7 +1,12 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from .forms import InvitationCodeForm, CustomUserCreationForm, CustomUserChangeForm
|
||||
from .models import InvitationCode
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic.edit import CreateView
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||
from django.contrib.auth import views as auth_views
|
||||
from .forms import InvitationCodeForm, CustomUserCreationForm, CustomUserChangeForm, PlayerCreationForm
|
||||
from .models import CustomUser, InvitationCode
|
||||
import uuid
|
||||
|
||||
def invitation_code_view(request):
|
||||
if request.method == 'POST':
|
||||
@ -52,4 +57,40 @@ def edit_profile(request):
|
||||
return redirect('edit_profile') # Or wherever you want to redirect
|
||||
else:
|
||||
form = CustomUserChangeForm(instance=request.user)
|
||||
return render(request, 'accounts/edit_profile.html', {'form': form})
|
||||
return render(request, 'accounts/edit_profile.html', {'form': form})
|
||||
|
||||
class HeadCoachCheckMixin(UserPassesTestMixin):
|
||||
def test_func(self):
|
||||
return self.request.user.is_superuser or self.request.user.coached_teams.exists()
|
||||
|
||||
class PlayerCreateView(LoginRequiredMixin, HeadCoachCheckMixin, CreateView):
|
||||
model = CustomUser
|
||||
form_class = PlayerCreationForm
|
||||
template_name = 'accounts/player_form.html'
|
||||
success_url = reverse_lazy('dashboard')
|
||||
|
||||
def form_valid(self, form):
|
||||
# Create player user
|
||||
player = form.save(commit=False)
|
||||
player.is_active = False # Player can only login after using invitation code
|
||||
player.save()
|
||||
|
||||
# Create invitation code for player
|
||||
InvitationCode.objects.create(code=str(uuid.uuid4()), user=player)
|
||||
|
||||
# Create parent users and invitation codes
|
||||
for email_field in ['parent1_email', 'parent2_email']:
|
||||
email = form.cleaned_data.get(email_field)
|
||||
if email:
|
||||
parent_user = CustomUser.objects.filter(email=email).first()
|
||||
if not parent_user:
|
||||
parent_user = CustomUser.objects.create(email=email, username=email, is_active=False)
|
||||
InvitationCode.objects.create(code=str(uuid.uuid4()), user=parent_user)
|
||||
|
||||
return redirect(self.success_url)
|
||||
|
||||
class MyLoginView(auth_views.LoginView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('dashboard')
|
||||
return super().get(request, *args, **kwargs)
|
||||
BIN
baseball_organisator/__pycache__/admin.cpython-313.pyc
Normal file
BIN
baseball_organisator/__pycache__/admin.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
11
baseball_organisator/admin.py
Normal file
11
baseball_organisator/admin.py
Normal file
@ -0,0 +1,11 @@
|
||||
from django.contrib import admin
|
||||
|
||||
def has_permission(self, request):
|
||||
if request.user.is_active and request.user.is_staff:
|
||||
if request.user.is_superuser:
|
||||
return True
|
||||
if hasattr(request.user, 'administered_clubs') and request.user.administered_clubs.exists():
|
||||
return True
|
||||
return False
|
||||
|
||||
admin.site.has_permission = has_permission.__get__(admin.site, admin.AdminSite)
|
||||
@ -16,6 +16,7 @@ Including another URLconf
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
import baseball_organisator.admin
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1,7 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import Event, Training, Game, GameResult
|
||||
from .models import Event, Training, Game, GameResult, EventParticipation
|
||||
|
||||
admin.site.register(Event)
|
||||
admin.site.register(Training)
|
||||
admin.site.register(Game)
|
||||
admin.site.register(GameResult)
|
||||
admin.site.register(GameResult)
|
||||
admin.site.register(EventParticipation)
|
||||
|
||||
28
calendars/migrations/0002_eventparticipation.py
Normal file
28
calendars/migrations/0002_eventparticipation.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-01 07:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('calendars', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EventParticipation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('status', models.CharField(choices=[('attending', 'Attending'), ('rejected', 'Rejected'), ('maybe', 'Maybe')], default='maybe', max_length=20)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='calendars.event')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('user', 'event')},
|
||||
},
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -34,4 +34,12 @@ class GameResult(models.Model):
|
||||
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):
|
||||
return f"Result for {self.game}"
|
||||
return f"Result for {self.game}"
|
||||
|
||||
class EventParticipation(models.Model):
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||
status = models.CharField(max_length=20, choices=[('attending', 'Attending'), ('rejected', 'Rejected'), ('maybe', 'Maybe')], default='maybe')
|
||||
|
||||
class Meta:
|
||||
unique_together = ('user', 'event')
|
||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
29
docs/phase5.md
Normal file
29
docs/phase5.md
Normal file
@ -0,0 +1,29 @@
|
||||
## Phase 5: Fortgeschrittene Funktionen und Backend
|
||||
|
||||
Diese Phase umfasst komplexere Features wie die Spieleranlage, die Abwesenheitsfunktion und das Backend-Management.
|
||||
|
||||
Schritt 1: Spieleranlage-Workflow
|
||||
|
||||
Implementiere in den accounts-Views einen Workflow für Headcoaches, um neue Spieler anzulegen.
|
||||
|
||||
Die Logik muss die automatische Generierung von Einladungscodes für den Spieler und optional für bis zu zwei Elternteile umfassen.
|
||||
|
||||
Die Überprüfung des Alters und die automatische Zuweisung eines Standard-Geburtsdatums muss implementiert werden.
|
||||
|
||||
Schritt 2: Abwesenheitsfunktion implementieren
|
||||
|
||||
Erstelle in accounts/models.py ein Modell AbsencePeriod mit Feldern start_date, end_date und einer Verknüpfung zum User.
|
||||
|
||||
Implementiere in den Views die Logik, die alle Termine in diesem Zeitraum automatisch auf "abgelehnt" setzt.
|
||||
|
||||
Schritt 3: Django-Admin-Bereich anpassen
|
||||
|
||||
Konfiguriere den Django-Admin-Bereich, sodass nur Club-Admins und der Superuser darauf zugreifen können.
|
||||
|
||||
Registriere die erstellten Modelle im Admin-Bereich, um die Verwaltung zu erleichtern.
|
||||
|
||||
Schritt 4: User-Migration und Logik für Rollen-Änderungen
|
||||
|
||||
Schreibe die Migrationsdateien für alle erstellten Modelle.
|
||||
|
||||
Implementiere die Logik für den Wechsel der Rollen, z. B. wenn ein Spieler über 18 Jahre alt wird.
|
||||
70
docs/traceback/trace2.log
Normal file
70
docs/traceback/trace2.log
Normal file
@ -0,0 +1,70 @@
|
||||
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 23, in <module>
|
||||
path('accounts/', include('accounts.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/accounts/urls.py", line 2, in <module>
|
||||
from . import views
|
||||
File "/home/mnagel/Projekte/baseball_organisator/accounts/views.py", line 2, in <module>
|
||||
class MyLoginView(auth_views.LoginView):
|
||||
^^^^^^^^^^
|
||||
NameError: name 'auth_views' is not defined
|
||||
|
||||
47
docs/traceback/trace3.log
Normal file
47
docs/traceback/trace3.log
Normal file
@ -0,0 +1,47 @@
|
||||
[01/Oct/2025 07:16:54] "GET / HTTP/1.1" 302 0
|
||||
[01/Oct/2025 07:17:22] "GET / HTTP/1.1" 200 540
|
||||
[01/Oct/2025 07:17:27] "POST /accounts/logout/ HTTP/1.1" 200 3420
|
||||
[01/Oct/2025 07:17:31] "GET / HTTP/1.1" 302 0
|
||||
[01/Oct/2025 07:17:31] "GET /accounts/login/?next=/ HTTP/1.1" 200 727
|
||||
[01/Oct/2025 07:17:37] "POST /accounts/login/?next=/ HTTP/1.1" 302 0
|
||||
[01/Oct/2025 07:17:37] "GET / HTTP/1.1" 200 540
|
||||
[01/Oct/2025 07:17:49] "GET /accounts/player/add/ HTTP/1.1" 200 2330
|
||||
Internal Server Error: /accounts/player/add/
|
||||
Traceback (most recent call last):
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
|
||||
response = get_response(request)
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/handlers/base.py", line 197, in _get_response
|
||||
response = wrapped_callback(request, *callback_args, **callback_kwargs)
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/views/generic/base.py", line 105, in view
|
||||
return self.dispatch(request, *args, **kwargs)
|
||||
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/contrib/auth/mixins.py", line 135, in dispatch
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/views/generic/base.py", line 144, in dispatch
|
||||
return handler(request, *args, **kwargs)
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/views/generic/edit.py", line 182, in post
|
||||
return super().post(request, *args, **kwargs)
|
||||
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/views/generic/edit.py", line 151, in post
|
||||
return self.form_valid(form)
|
||||
~~~~~~~~~~~~~~~^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/accounts/views.py", line 85, in form_valid
|
||||
parent_user, created = CustomUser.objects.get_or_create(email=email, defaults={'username': email, 'is_active': False})
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/db/models/manager.py", line 87, in manager_method
|
||||
return getattr(self.get_queryset(), name)(*args, **kwargs)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/db/models/query.py", line 946, in get_or_create
|
||||
return self.get(**kwargs), False
|
||||
~~~~~~~~^^^^^^^^^^
|
||||
File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/db/models/query.py", line 636, in get
|
||||
raise self.model.MultipleObjectsReturned(
|
||||
...<5 lines>...
|
||||
)
|
||||
accounts.models.CustomUser.MultipleObjectsReturned: get() returned more than one CustomUser -- it returned 2!
|
||||
[01/Oct/2025 07:18:48] "POST /accounts/player/add/ HTTP/1.1" 500 112859
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user