--- /dev/null
+ # Created by https://www.gitignore.io/api/django
+# Edit at https://www.gitignore.io/?templates=django
+
+### Django ###
+*.log
+*.pot
+*.pyc
+__pycache__/
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+media
+
+# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
+# in your Git repository. Update and uncomment the following line accordingly.
+# <django-project-name>/staticfiles/
+
+### Django.Python Stack ###
+# Byte-compiled / optimized / DLL files
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# End of https://www.gitignore.io/api/django
--- /dev/null
+{
+ "python.pythonPath": "/home/john/devel/python/Sportteam_project/bin/python3"
+}
--- /dev/null
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sportteam.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+from django.contrib import admin
+
+# Register your models here.
--- /dev/null
+from django.apps import AppConfig
+
+
+class PagesConfig(AppConfig):
+ name = 'pages'
--- /dev/null
+from django.db import models
+
+# Create your models here.
--- /dev/null
+{% extends "base.html" %}
+{% block header %}
+PAGES
+{% endblock %}
\ No newline at end of file
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from django.urls import path, include
+from . import views
+
+urlpatterns = [
+ path('', views.index, name='index'),
+]
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
+
+
+def index(req):
+ return render(req, 'pages/index.html')
--- /dev/null
+asgiref==3.2.3
+astroid==2.3.3
+Django==3.0.2
+isort==4.3.21
+lazy-object-proxy==1.4.3
+mccabe==0.6.1
+mysqlclient==1.4.6
+pylint==2.4.4
+pytz==2019.3
+six==1.13.0
+sqlparse==0.3.0
+typed-ast==1.4.0
+wrapt==1.11.2
--- /dev/null
+"""
+ASGI config for sportteam project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sportteam.settings')
+
+application = get_asgi_application()
--- /dev/null
+"""
+Django settings for sportteam project.
+
+Generated by 'django-admin startproject' using Django 3.0.2.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.0/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '6c&5ge@-y_n**tt=2932w%r4c41v#e$2sco@@^69n4#xqsx0!f'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'pages',
+ 'team_management',
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'rest_framework',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'sportteam.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'sportteam.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql',
+ 'NAME': 'sportteam',
+ 'USER': 'sportteam',
+ 'PASSWORD': 'sportteam',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.0/topics/i18n/
+
+LANGUAGE_CODE = 'de'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.0/howto/static-files/
+
+STATIC_URL = '/static/'
+STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
--- /dev/null
+"""sportteam URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/3.0/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path, include
+
+urlpatterns = [
+ path('', include('pages.urls')),
+ path('team_management/', include('team_management.urls')),
+ path('admin/', admin.site.urls),
+]
--- /dev/null
+"""
+WSGI config for sportteam project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sportteam.settings')
+
+application = get_wsgi_application()
--- /dev/null
+from django.contrib import admin
+
+# Register your models here.
--- /dev/null
+from .models import Player, Team
+from rest_framework import viewsets, permissions
+from .serializers import PlayerSerializer, TeamSerializer
+
+
+class PlayerViewSet(viewsets.ModelViewSet):
+ queryset = Player.objects.all()
+ permission_classes = [
+ permissions.AllowAny
+ ]
+ serializer_class = PlayerSerializer
+
+
+class TeamViewSet(viewsets.ModelViewSet):
+ queryset = Team.objects.all()
+ permission_classes = [
+ permissions.AllowAny
+ ]
+ serializer_class = TeamSerializer
--- /dev/null
+from django.apps import AppConfig
+
+
+class TeamManagementConfig(AppConfig):
+ name = 'team_management'
--- /dev/null
+# Generated by Django 3.0.2 on 2020-01-02 22:44
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Event',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('begin', models.DateTimeField()),
+ ('end', models.DateTimeField()),
+ ('optional', models.TextField(blank=True, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Location',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=50)),
+ ('street', models.CharField(blank=True, max_length=100, null=True)),
+ ('zip', models.IntegerField(blank=True, null=True)),
+ ('city', models.CharField(blank=True, max_length=100, null=True)),
+ ('additional', models.CharField(blank=True, max_length=100, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Merch',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('item', models.CharField(blank=True, max_length=50, null=True)),
+ ('costs', models.FloatField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Player',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('birthdate', models.DateField(blank=True, null=True)),
+ ('dsvid', models.IntegerField(blank=True, null=True)),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Game',
+ fields=[
+ ('event_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='team_management.Event')),
+ ('home', models.BooleanField()),
+ ('opponent', models.CharField(max_length=50)),
+ ('score_team', models.IntegerField(blank=True, null=True)),
+ ('score_opponent', models.IntegerField(blank=True, null=True)),
+ ],
+ bases=('team_management.event',),
+ ),
+ migrations.CreateModel(
+ name='Training',
+ fields=[
+ ('event_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='team_management.Event')),
+ ],
+ bases=('team_management.event',),
+ ),
+ migrations.CreateModel(
+ name='Team',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=50)),
+ ('min_age', models.IntegerField(blank=True, default=0, null=True)),
+ ('max_age', models.IntegerField(blank=True, default=999, null=True)),
+ ('players', models.ManyToManyField(blank=True, to='team_management.Player')),
+ ('trainers', models.ManyToManyField(blank=True, related_name='trainers', to='team_management.Player')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Task',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('task', models.TextField()),
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Event')),
+ ('player', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Player')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='PlayerState',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('state', models.CharField(choices=[('y', 'Ja'), ('n', 'Nein'), ('p', 'Vielleicht')], max_length=1)),
+ ('reason', models.CharField(blank=True, max_length=180, null=True)),
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Event')),
+ ('player', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Player')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Order',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('quantity', models.IntegerField(default=1)),
+ ('merch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Merch')),
+ ('player', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Player')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='merch',
+ name='orders',
+ field=models.ManyToManyField(blank=True, through='team_management.Order', to='team_management.Player'),
+ ),
+ migrations.AddField(
+ model_name='event',
+ name='location',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='team_management.Location'),
+ ),
+ migrations.AddField(
+ model_name='event',
+ name='state',
+ field=models.ManyToManyField(blank=True, related_name='event_player_state', through='team_management.PlayerState', to='team_management.Player'),
+ ),
+ migrations.AddField(
+ model_name='event',
+ name='tasks',
+ field=models.ManyToManyField(blank=True, through='team_management.Task', to='team_management.Player'),
+ ),
+ migrations.AddField(
+ model_name='event',
+ name='team',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='team_management.Team'),
+ ),
+ ]
--- /dev/null
+from django.db import models
+from django.contrib.auth.models import User
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+
+# Create your models here.
+
+
+class Player(models.Model):
+ birthdate = models.DateField(blank=True, null=True)
+ dsvid = models.IntegerField(blank=True, null=True)
+ user = models.OneToOneField(User, on_delete=models.CASCADE)
+
+ def __str__(self):
+ if not self.user.first_name and not self.user.last_name:
+ return self.user.username
+ return self.user.first_name + ', ' + self.user.last_name
+
+
+@receiver(post_save, sender=User)
+def create_player(sender, instance, created, **kwargs):
+ if created:
+ Player.objects.create(user=instance)
+
+
+@receiver(post_save, sender=User)
+def save_player(sender, instance, **kwargs):
+ instance.player.save()
+
+
+class Team(models.Model):
+ name = models.CharField(max_length=50)
+ min_age = models.IntegerField(default=0, blank=True, null=True)
+ max_age = models.IntegerField(default=999, blank=True, null=True)
+ players = models.ManyToManyField(Player, blank=True)
+ trainers = models.ManyToManyField(Player,
+ related_name='trainers', blank=True)
+
+ def __str__(self):
+ return self.name
+
+
+class Location(models.Model):
+ name = models.CharField(max_length=50)
+ street = models.CharField(max_length=100, blank=True, null=True)
+ zip = models.IntegerField(blank=True, null=True)
+ city = models.CharField(max_length=100, blank=True, null=True)
+ additional = models.CharField(max_length=100, blank=True, null=True)
+
+ def __str__(self):
+ return self.name
+
+
+class Event(models.Model):
+ begin = models.DateTimeField()
+ end = models.DateTimeField()
+ location = models.ForeignKey(Location, on_delete=models.CASCADE,
+ blank=True, null=True)
+ team = models.ForeignKey(Team, on_delete=models.CASCADE)
+ tasks = models.ManyToManyField(Player, through='Task', blank=True)
+ state = models.ManyToManyField(Player,
+ through='PlayerState',
+ related_name='event_player_state',
+ blank=True)
+ optional = models.TextField(blank=True, null=True)
+
+
+class Task(models.Model):
+ player = models.ForeignKey(Player, on_delete=models.CASCADE)
+ event = models.ForeignKey(Event, on_delete=models.CASCADE)
+ task = models.TextField()
+
+
+class Game(Event):
+ home = models.BooleanField()
+ opponent = models.CharField(max_length=50)
+ score_team = models.IntegerField(blank=True, null=True)
+ score_opponent = models.IntegerField(blank=True, null=True)
+
+ def __str__(self):
+ if self.home:
+ return self.team + ' - ' + self.opponent
+ else:
+ return self.opponent + ' - ' + self.team
+
+
+class Training(Event):
+ pass
+
+
+class PlayerState(models.Model):
+ ANSWERS = (
+ ('y', 'Ja'),
+ ('n', 'Nein'),
+ ('p', 'Vielleicht'),
+ )
+ player = models.ForeignKey(Player, on_delete=models.CASCADE)
+ event = models.ForeignKey(Event, on_delete=models.CASCADE)
+ state = models.CharField(max_length=1, choices=ANSWERS)
+ reason = models.CharField(max_length=180, blank=True, null=True)
+
+
+class Merch(models.Model):
+ item = models.CharField(max_length=50, blank=True, null=True)
+ costs = models.FloatField()
+ orders = models.ManyToManyField(Player, through='Order', blank=True)
+
+
+class Order(models.Model):
+ player = models.ForeignKey(Player, on_delete=models.CASCADE)
+ merch = models.ForeignKey(Merch, on_delete=models.CASCADE)
+ quantity = models.IntegerField(default=1)
--- /dev/null
+from rest_framework import serializers
+from .models import Player, Team
+
+
+class PlayerSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Player
+ fields = '__all__'
+
+
+class TeamSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Team
+ fields = '__all__'
--- /dev/null
+{% extends "base.html" %}
+{% block header %} team management {% endblock %}
\ No newline at end of file
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from django.urls import path, include
+from rest_framework import routers
+from .api import PlayerViewSet, TeamViewSet
+from . import views
+
+router = routers.DefaultRouter()
+router.register('api/players', PlayerViewSet, 'players')
+router.register('api/teams', TeamViewSet, 'teams')
+urlpatterns = [
+ path('', views.index, name='index'),
+]
+urlpatterns.extend(router.urls)
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
+
+
+def index(req):
+ return render(req, 'team_management/index.html')
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
+ {% load static %}
+ <link rel="stylesheet" type="text/css" href="{% static 'base.css' %}" />
+ <script src="{% static 'base.js' %}"></script>
+ <title>{% block title %} Sportteam Hamburg {% endblock %}</title>
+ </head>
+ <body>
+ <div id="header">{% block header %}<div id="headertitle">Sportteam Hamburg</div>{% endblock %}</div>
+ <div id="nav">{% block nav %}{% endblock %}</div>
+ <div id="main">{% block main %}{% endblock %}</div>
+ <div id="footer">{% block footer %}{% endblock %}</div>
+ </body>
+</html>