From dafdd2d7c1fc8b3643162e99565b82a8d2aa5644 Mon Sep 17 00:00:00 2001 From: wildcat3333 <118195627+wildcat3333@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:17:02 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=BF=D0=BE=20ER-=D0=B4=D0=B8=D0=B0=D0=B3=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=BC=D0=B5=20=D0=B8=20=D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=B0=20(#62)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Реализация ER-диаграмы проекта * Добавление моделей и отображение моделей в админке * Удаление лишних файлов ER-диаграмм * Delete migrations * Merge models users * Create new migrations models for test * Обновленная ER-диаграмма * Испарвление ошибки flake8 DJ08 Model * Реализация моделей по ER-диаграмме и админка * Добавление в моделях обязательные поля * Изменение в моделях с обязательными полями on_delete=CASCADE --------- Co-authored-by: Konstantin Raikhert --- README.md | 4 +- adaptive_hockey_federation/main/admin.py | 176 +++--- .../main/migrations/0001_initial.py | 183 +++--- .../0002_alter_player_patronymic.py | 18 - adaptive_hockey_federation/main/models.py | 539 +++++++++--------- 5 files changed, 422 insertions(+), 498 deletions(-) delete mode 100644 adaptive_hockey_federation/main/migrations/0002_alter_player_patronymic.py diff --git a/README.md b/README.md index 2eb9ee12..05c95c51 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,11 @@ 1. [БРИФ](https://docs.google.com/document/d/1iHkA4Al-H-ppALPJDLMhb_Dl-ciRHH2npM6YRa2HQwg/edit) - 1.2. [ER - диаграмма сущностей](docs/ER_Diagram.jpg) - 1.1. [Инструкции и ритуалы на проекте](docs/materials/instructions.md) -1.2. [ER - диаграмма сущностей](docs/) +1.2. [ER - диаграмма сущностей](docs/ER_Diagram.jpg) diff --git a/adaptive_hockey_federation/main/admin.py b/adaptive_hockey_federation/main/admin.py index 133c5ea0..771a6928 100644 --- a/adaptive_hockey_federation/main/admin.py +++ b/adaptive_hockey_federation/main/admin.py @@ -1,186 +1,174 @@ from django.contrib import admin from main.models import ( City, - Competition, Diagnosis, Discipline, - Gender, + DisciplineLevel, + DisciplineName, + Document, + Nosology, Player, - PlayerTeam, - Position, - Qualification, + StaffMember, + StaffTeamMember, Team, - TeamCompetition, - Trainer, - TrainerTeam, ) -class PlayerInline(admin.TabularInline): - model = PlayerTeam - - -class TrainerInline(admin.TabularInline): - model = TrainerTeam - - class CityAdmin(admin.ModelAdmin): list_display = ( 'pk', 'name' ) search_fields = ('name',) + ordering = ['name'] -class GenderAdmin(admin.ModelAdmin): +class NosologyAdmin(admin.ModelAdmin): list_display = ( 'pk', 'name' ) search_fields = ('name',) + ordering = ['name'] -class DisciplineAdmin(admin.ModelAdmin): +class DiagnosisAdmin(admin.ModelAdmin): list_display = ( 'pk', - 'name' + 'name', + 'nosology' ) - search_fields = ('name',) + search_fields = ( + 'pk', 'name', 'nosology',) + ordering = ['name'] -class PositionAdmin(admin.ModelAdmin): +class DisciplineNameAdmin(admin.ModelAdmin): list_display = ( 'pk', 'name' ) search_fields = ('name',) + ordering = ['name'] -class QualificationAdmin(admin.ModelAdmin): +class DisciplineLevelAdmin(admin.ModelAdmin): list_display = ( 'pk', 'name' ) search_fields = ('name',) + ordering = ['name'] -class TrainerTeamAdmin(admin.ModelAdmin): +class DisciplineAdmin(admin.ModelAdmin): list_display = ( - 'trainer', - 'team', + 'pk', + 'discipline_name', + 'discipline_level' ) - search_fields = ('trainer', 'team',) + search_fields = ('discipline_name', 'discipline_level',) + ordering = ['discipline_name'] -class TrainerAdmin(admin.ModelAdmin): +class DocumentAdmin(admin.ModelAdmin): list_display = ( 'pk', - 'surname', 'name', - 'patronymic', - 'description', + 'file' ) - search_fields = ('pk', 'surname', 'name', 'patronymic', 'description',) + search_fields = ('name', 'file',) + ordering = ['name'] -class PlayerAdmin(admin.ModelAdmin): +class StaffMemberAdmin(admin.ModelAdmin): list_display = ( 'pk', 'surname', 'name', 'patronymic', - 'date_of_birth', - 'diagnosis', - 'gender', - 'identification_card', - ) - search_fields = ( - 'pk', - 'surname', - 'name', - 'patronymic', - 'date_of_birth', - 'diagnosis', - 'gender', - 'identification_card', + 'phone' ) + search_fields = ('pk', 'surname', 'name', 'patronymic', 'phone',) -class DiagnosisAdmin(admin.ModelAdmin): +class StaffTeamMemberAdmin(StaffMemberAdmin): list_display = ( 'pk', - 'class_name', - 'is_wheeled', - 'description', + 'staff_member', + 'staff_position', + 'qualification', + 'notes' ) search_fields = ( - 'pk', 'class_name', 'description',) + 'pk', + 'staff_member', + 'staff_position', + 'qualification', + 'notes' + ) -class PlayerTeamAdmin(admin.ModelAdmin): +class PlayerAdmin(admin.ModelAdmin): list_display = ( 'pk', - 'player', - 'team', - 'qualification', + 'surname', + 'name', + 'patronymic', + 'birthday', + 'gender', + 'diagnosis', + 'discipline', + 'level_revision', + 'position', 'number', 'is_captain', 'is_assistent', + 'identity_document', ) search_fields = ( - 'pk', 'player', 'team', 'qualification',) - - -class CompetitionAdmin(admin.ModelAdmin): - list_display = ( 'pk', - 'city', + 'surname', + 'name', + 'patronymic', + 'birthday', + 'gender', + 'diagnosis', + 'discipline', + 'level_revision', + 'position', 'number', - 'date', - 'duration', - 'is_active', + 'identity_document', ) - search_fields = ( - 'pk', 'city', 'number', 'duration',) - list_filter = ('date',) + ordering = ['surname', 'name', 'patronymic', 'birthday'] -class TeamCompetitionAdmin(admin.ModelAdmin): +class TeamAdmin(admin.ModelAdmin): list_display = ( 'pk', - 'team', - 'competition', + 'name', + 'city', + 'staff_team_member', + 'discipline_name' ) search_fields = ( - 'pk', 'team', 'competition',) - - -@admin.register(Team) -class TeamAdmin(admin.ModelAdmin): - list_display = ( + 'pk', 'name', 'city', - 'discipline', - 'composition', - 'age', - 'pk', + 'staff_team_member', + 'discipline_name' ) - search_fields = [ - 'pk', 'name', 'city', 'discipline', 'composition', 'age'] - autocomplete_fields = ['city', 'discipline'] - inlines = [PlayerInline, TrainerInline] + ordering = ['name'] +admin.site.register(City, CityAdmin) admin.site.register(Diagnosis, DiagnosisAdmin) admin.site.register(Discipline, DisciplineAdmin) -admin.site.register(Gender, GenderAdmin) -admin.site.register(City, CityAdmin) +admin.site.register(DisciplineLevel, DisciplineLevelAdmin) +admin.site.register(DisciplineName, DisciplineNameAdmin) +admin.site.register(Document, DocumentAdmin) +admin.site.register(Nosology, NosologyAdmin) admin.site.register(Player, PlayerAdmin) -admin.site.register(Position, PositionAdmin) -# admin.site.register(Team, TeamAdmin) -admin.site.register(Qualification, QualificationAdmin) -admin.site.register(PlayerTeam, PlayerTeamAdmin) -admin.site.register(Trainer, TrainerAdmin) -admin.site.register(TrainerTeam, TrainerTeamAdmin) -admin.site.register(Competition, CompetitionAdmin) -admin.site.register(TeamCompetition, TeamCompetitionAdmin) +admin.site.register(StaffTeamMember, StaffTeamMemberAdmin) +admin.site.register(StaffMember, StaffMemberAdmin) +admin.site.register(Team, TeamAdmin) diff --git a/adaptive_hockey_federation/main/migrations/0001_initial.py b/adaptive_hockey_federation/main/migrations/0001_initial.py index 4a85acf3..3e6f9685 100644 --- a/adaptive_hockey_federation/main/migrations/0001_initial.py +++ b/adaptive_hockey_federation/main/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.8 on 2023-12-14 14:00 +# Generated by Django 4.2.8 on 2023-12-16 13:42 import django.db.models.deletion from django.db import migrations, models @@ -16,36 +16,18 @@ class Migration(migrations.Migration): name='City', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), ], options={ 'verbose_name': 'Город', 'verbose_name_plural': 'Города', }, ), - migrations.CreateModel( - name='Competition', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), - ('number', models.CharField(help_text='Номер соревнований', max_length=256, verbose_name='Номер соревнований')), - ('date', models.DateField(help_text='Дата соревнований', verbose_name='Дата соревнований')), - ('duration', models.IntegerField(default=0, help_text='Длительность', verbose_name='Длительность')), - ('is_active', models.BooleanField(default=True, help_text='Активно', verbose_name='Активно')), - ('city', models.ForeignKey(blank=True, help_text='Город', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.city', verbose_name='Город')), - ], - options={ - 'verbose_name': 'Соревнование', - 'verbose_name_plural': 'Соревнования', - }, - ), migrations.CreateModel( name='Diagnosis', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('class_name', models.CharField(help_text='Класс', max_length=10, unique=True, verbose_name='Класс')), - ('is_wheeled', models.BooleanField(default=False, help_text='На коляске', verbose_name='На коляске')), - ('description', models.TextField(blank=True, help_text='Описание', verbose_name='Описание')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), ], options={ 'verbose_name': 'Диагноз', @@ -56,7 +38,6 @@ class Migration(migrations.Migration): name='Discipline', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), ], options={ 'verbose_name': 'Дисциплина', @@ -64,150 +45,150 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='Gender', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), - ], - options={ - 'verbose_name': 'Пол', - 'verbose_name_plural': 'Пол', - }, - ), - migrations.CreateModel( - name='Player', + name='DisciplineLevel', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('surname', models.CharField(default='--пусто--', help_text='Фамилия', max_length=256, verbose_name='Фамилия')), - ('name', models.CharField(default='--пусто--', help_text='Имя', max_length=256, verbose_name='Имя')), - ('patronymic', models.CharField(blank=True, default='--пусто--', help_text='Отчество', max_length=256, verbose_name='Отчество')), - ('date_of_birth', models.DateField(blank=True, help_text='Дата рождения', null=True, verbose_name='Дата рождения')), - ('identification_card', models.TextField(default=0, help_text='Удостоверение личности', verbose_name='Удостоверение личности')), - ('diagnosis', models.ForeignKey(default=0, help_text='Диагноз', on_delete=django.db.models.deletion.CASCADE, related_name='diagnosis', to='main.diagnosis', verbose_name='Диагноз')), - ('gender', models.ForeignKey(default=0, help_text='Пол', on_delete=django.db.models.deletion.CASCADE, related_name='gender', to='main.gender', verbose_name='Пол')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), ], options={ - 'verbose_name': 'Игрок', - 'verbose_name_plural': 'Игроки', - 'ordering': ('surname', 'name', 'patronymic'), - 'abstract': False, - 'default_related_name': 'players', + 'verbose_name': 'Классификация/статус дисциплины', + 'verbose_name_plural': 'Классификация/статусы дисциплин', }, ), migrations.CreateModel( - name='Position', + name='DisciplineName', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), ], options={ - 'verbose_name': 'Игоровая позиция', - 'verbose_name_plural': 'Игровые позиции', + 'verbose_name': 'Название дисциплины', + 'verbose_name_plural': 'Названия дисциплин', }, ), migrations.CreateModel( - name='Qualification', + name='Document', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, unique=True, verbose_name='Название')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), + ('file', models.FileField(max_length=256, upload_to='documents')), ], options={ - 'verbose_name': 'Квалификация', - 'verbose_name_plural': 'Квалификации', + 'verbose_name': 'Документ', + 'verbose_name_plural': 'Документы', }, ), migrations.CreateModel( - name='Team', + name='Nosology', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='Название', max_length=256, verbose_name='Название')), - ('composition', models.CharField(default='--пусто--', help_text='Состав', max_length=256, verbose_name='Состав')), - ('age', models.CharField(default='--пусто--', help_text='Возраст', max_length=256, verbose_name='Возраст')), - ('city', models.ForeignKey(blank=True, help_text='Город откуда команда', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.city', verbose_name='Город откуда команда')), - ('discipline', models.ForeignKey(blank=True, help_text='Дисциплина команды', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.discipline', verbose_name='Дисциплина команды')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), ], options={ - 'verbose_name': 'Команда', - 'verbose_name_plural': 'Команды', - 'default_related_name': 'teams', + 'verbose_name': 'Нозология', + 'verbose_name_plural': 'Нозология', }, ), migrations.CreateModel( - name='Trainer', + name='StaffMember', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('surname', models.CharField(default='--пусто--', help_text='Фамилия', max_length=256, verbose_name='Фамилия')), - ('name', models.CharField(default='--пусто--', help_text='Имя', max_length=256, verbose_name='Имя')), - ('patronymic', models.CharField(blank=True, default='--пусто--', help_text='Отчество', max_length=256, verbose_name='Отчество')), - ('date_of_birth', models.DateField(blank=True, help_text='Дата рождения', null=True, verbose_name='Дата рождения')), - ('description', models.TextField(help_text='Описание', verbose_name='Описание')), + ('surname', models.CharField(default='', help_text='Фамилия', max_length=256, verbose_name='Фамилия')), + ('name', models.CharField(default='', help_text='Имя', max_length=256, verbose_name='Имя')), + ('patronymic', models.CharField(blank=True, default='', help_text='Отчество', max_length=256, verbose_name='Отчество')), + ('phone', models.CharField(blank=True, default='', help_text='Номер телефона', max_length=256, verbose_name='Номер телефона')), ], options={ - 'verbose_name': 'Тренер', - 'verbose_name_plural': 'Тренеры', + 'verbose_name': 'Сотрудник', + 'verbose_name_plural': 'Сотрудники', }, ), migrations.CreateModel( - name='TrainerTeam', + name='StaffTeamMember', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('team', models.ForeignKey(help_text='Команда', on_delete=django.db.models.deletion.CASCADE, to='main.team', verbose_name='Команда')), - ('trainer', models.ForeignKey(help_text='Тренер команды', on_delete=django.db.models.deletion.CASCADE, to='main.trainer', verbose_name='Тренер команды')), + ('staff_position', models.CharField(choices=[('trainer', 'тренер'), ('other', 'другой')], default='', help_text='Статус сотрудника', max_length=256, verbose_name='Статус сотрудника')), + ('qualification', models.CharField(blank=True, default='', help_text='Квалификация', max_length=256, verbose_name='Квалификация')), + ('notes', models.TextField(blank=True, default='', help_text='Описание', verbose_name='Описание')), + ('staff_member', models.ForeignKey(default='', help_text='Сотрудник', on_delete=django.db.models.deletion.SET_DEFAULT, to='main.staffmember', verbose_name='Сотрудник')), ], options={ - 'verbose_name': 'Тренер --> команда', - 'verbose_name_plural': 'Тренер --> команды', - 'default_related_name': 'trainer_teams', + 'verbose_name': 'Сотрудник команды', + 'verbose_name_plural': 'Сотрудники команды', }, ), migrations.CreateModel( - name='TeamCompetition', + name='Team', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('competition', models.ForeignKey(help_text='Соревнование', on_delete=django.db.models.deletion.CASCADE, to='main.competition', verbose_name='Соревнование')), - ('team', models.ForeignKey(help_text='Команда', on_delete=django.db.models.deletion.CASCADE, to='main.team', verbose_name='Команда')), + ('name', models.CharField(help_text='Наименование', max_length=256, unique=True, verbose_name='Наименование')), + ('city', models.ForeignKey(default='', help_text='Город откуда команда', on_delete=django.db.models.deletion.SET_DEFAULT, to='main.city', verbose_name='Город откуда команда')), + ('discipline_name', models.ForeignKey(default='', help_text='Дисциплина команды', on_delete=django.db.models.deletion.SET_DEFAULT, to='main.disciplinename', verbose_name='Дисциплина команды')), + ('staff_team_member', models.ForeignKey(default='', help_text='Сотрудник команды', on_delete=django.db.models.deletion.SET_DEFAULT, to='main.staffteammember', verbose_name='Сотрудник команды')), ], options={ - 'verbose_name': 'Соревнование --> команда', - 'verbose_name_plural': 'Совревнования --> команды', - 'default_related_name': 'team_competitions', + 'verbose_name': 'Команда', + 'verbose_name_plural': 'Команды', + 'default_related_name': 'teams', }, ), migrations.CreateModel( - name='PlayerTeam', + name='Player', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('number', models.CharField(help_text='Номер игорока', max_length=256, verbose_name='Номер игорока')), + ('surname', models.CharField(default='', help_text='Фамилия', max_length=256, verbose_name='Фамилия')), + ('name', models.CharField(default='', help_text='Имя', max_length=256, verbose_name='Имя')), + ('patronymic', models.CharField(blank=True, default='', help_text='Отчество', max_length=256, verbose_name='Отчество')), + ('birthday', models.DateField(help_text='Дата рождения', verbose_name='Дата рождения')), + ('gender', models.CharField(choices=[('male', 'Мужской'), ('female', 'Женский')], default='', help_text='Пол', max_length=256, verbose_name='Пол')), + ('level_revision', models.TextField(blank=True, default='', help_text='Уровень ревизии', verbose_name='Уровень ревизии')), + ('position', models.CharField(choices=[('striker', 'Нападающий'), ('bobber', 'Поплавок'), ('goalkeeper', 'Вратарь'), ('defender', 'Защитник')], default='', help_text='Игровая позиция', max_length=256, verbose_name='Игровая позиция')), + ('number', models.IntegerField(default=0, help_text='Номер игрока', verbose_name='Номер игрока')), ('is_captain', models.BooleanField(default=False, help_text='Капитан', verbose_name='Капитан')), ('is_assistent', models.BooleanField(default=False, help_text='Ассистент', verbose_name='Ассистент')), - ('player', models.ForeignKey(help_text='Игрок', on_delete=django.db.models.deletion.CASCADE, related_name='player_teams', to='main.player', verbose_name='Игрок')), - ('position', models.ForeignKey(blank=True, help_text='Позиция игрока', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.position', verbose_name='Позиция игрока')), - ('qualification', models.ForeignKey(blank=True, help_text='Квалификация игрока', null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.qualification', verbose_name='Квалификация игрока')), - ('team', models.ForeignKey(help_text='Команда', on_delete=django.db.models.deletion.CASCADE, related_name='team_players', to='main.team', verbose_name='Команда')), + ('identity_document', models.TextField(blank=True, default='', help_text='Удостоверение личности', verbose_name='Удостоверение личности')), + ('diagnosis', models.ForeignKey(default=0, help_text='Диагноз', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='player_diagnosis', to='main.diagnosis', verbose_name='Диагноз')), + ('discipline', models.ForeignKey(default='', help_text='Дисциплина', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='player_disciplines', to='main.discipline', verbose_name='Дисциплина')), + ('document', models.ForeignKey(blank=True, default='', help_text='Документ', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='player_documemts', to='main.document', verbose_name='Документ')), + ('team', models.ManyToManyField(help_text='Команда', related_name='team_players', to='main.team', verbose_name='Команда')), ], options={ - 'verbose_name': 'Игрок команды', - 'verbose_name_plural': 'Игроки команды', + 'verbose_name': 'Игрок', + 'verbose_name_plural': 'Игроки', + 'ordering': ('surname', 'name', 'patronymic'), + 'abstract': False, + 'default_related_name': 'players', }, ), - migrations.AddConstraint( - model_name='trainerteam', - constraint=models.UniqueConstraint(fields=('trainer', 'team'), name='trainer_teams_unique'), + migrations.AddField( + model_name='discipline', + name='discipline_level', + field=models.ForeignKey(help_text='Класс/статус', max_length=10, on_delete=django.db.models.deletion.CASCADE, related_name='disciplines', to='main.disciplinelevel', verbose_name='Класс/статус'), ), - migrations.AddConstraint( - model_name='teamcompetition', - constraint=models.UniqueConstraint(fields=('team', 'competition'), name='competition_teams_unique'), + migrations.AddField( + model_name='discipline', + name='discipline_name', + field=models.ForeignKey(help_text='Название дисциплины', max_length=10, on_delete=django.db.models.deletion.CASCADE, related_name='disciplines', to='main.disciplinename', verbose_name='Название дисциплины'), + ), + migrations.AddField( + model_name='diagnosis', + name='nosology', + field=models.ForeignKey(help_text='Нозология', max_length=10, on_delete=django.db.models.deletion.CASCADE, related_name='diagnosis', to='main.nosology', verbose_name='Нозология'), ), migrations.AddConstraint( model_name='team', - constraint=models.UniqueConstraint(fields=('name', 'city', 'discipline'), name='team_city_unique'), + constraint=models.UniqueConstraint(fields=('name', 'city', 'discipline_name'), name='team_city_unique'), + ), + migrations.AddConstraint( + model_name='player', + constraint=models.UniqueConstraint(fields=('name', 'surname', 'patronymic', 'birthday'), name='player_unique'), ), migrations.AddConstraint( model_name='player', - constraint=models.UniqueConstraint(fields=('name', 'surname', 'patronymic', 'date_of_birth'), name='player_unique'), + constraint=models.UniqueConstraint(fields=('position', 'number'), name='player_position_number_unique'), ), migrations.AddConstraint( - model_name='competition', - constraint=models.UniqueConstraint(fields=('city', 'number', 'date'), name='competitions_unique'), + model_name='discipline', + constraint=models.UniqueConstraint(fields=('discipline_name', 'discipline_level'), name='discipline_name_level_unique'), ), ] diff --git a/adaptive_hockey_federation/main/migrations/0002_alter_player_patronymic.py b/adaptive_hockey_federation/main/migrations/0002_alter_player_patronymic.py deleted file mode 100644 index ffafb0be..00000000 --- a/adaptive_hockey_federation/main/migrations/0002_alter_player_patronymic.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-06 21:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('main', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='player', - name='patronymic', - field=models.CharField(blank=True, default='', max_length=256, verbose_name='Отчество'), - ), - ] diff --git a/adaptive_hockey_federation/main/models.py b/adaptive_hockey_federation/main/models.py index 1fee1306..5ab7c177 100644 --- a/adaptive_hockey_federation/main/models.py +++ b/adaptive_hockey_federation/main/models.py @@ -1,16 +1,34 @@ from django.db import models from django.utils.translation import gettext_lazy as _ -NAME_FIELD_LENGTH = 256 -EMPTY_VALUE_DISPLAY = '--пусто--' +CHAR_FIELD_LENGTH = 256 +EMPTY_VALUE_DISPLAY = '' CLASS_FIELD_LENGTH = 10 +DEFAULT_VALUE = 0 + +GENDER_CHOICES = ( + ('male', 'Мужской'), + ('female', 'Женский'), +) + +PLAYER_POSITION_CHOICES = ( + ('striker', 'Нападающий'), + ('bobber', 'Поплавок'), + ('goalkeeper', 'Вратарь'), + ('defender', 'Защитник'), +) + +STAFF_POSITION_CHOICES = ( + ('trainer', 'тренер'), + ('other', 'другой'), +) class BaseUniqueName(models.Model): name = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Название'), - help_text=_('Название'), + max_length=CHAR_FIELD_LENGTH, + verbose_name=_('Наименование'), + help_text=_('Наименование'), unique=True, ) @@ -22,229 +40,246 @@ def __str__(self): return self.name -class BasePerson(models.Model): +class City(BaseUniqueName): """ - Абстрактная модель с базовой персональной информацией. + Модель Город. """ - surname = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Фамилия'), - help_text=_('Фамилия'), - default=EMPTY_VALUE_DISPLAY - ) - name = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Имя'), - help_text=_('Имя'), - default=EMPTY_VALUE_DISPLAY - ) - patronymic = models.CharField( - max_length=NAME_FIELD_LENGTH, - blank=True, - verbose_name=_('Отчество'), - help_text=_('Отчество'), - default=EMPTY_VALUE_DISPLAY - ) - date_of_birth = models.DateField( - verbose_name=_('Дата рождения'), - help_text=_('Дата рождения'), - null=True, - blank=True - ) - class Meta: - ordering = ('surname', 'name', 'patronymic') - abstract = True + verbose_name = 'Город' + verbose_name_plural = 'Города' def __str__(self): - return ' '.join([self.surname, self.name, self.patronymic]) + return self.name -class Diagnosis(models.Model): +class DisciplineName(BaseUniqueName): """ - Модель Диагноз. + Модель название дисциплин + (следж-хоккей, хоккей для незрячих, спец. хоккей). """ - class_name = models.CharField( - verbose_name=_('Класс'), - help_text=_('Класс'), - max_length=CLASS_FIELD_LENGTH, - unique=True - ) - is_wheeled = models.BooleanField( - default=False, - verbose_name=_('На коляске'), - help_text=_('На коляске') - ) - description = models.TextField( - verbose_name=_('Описание'), - help_text=_('Описание'), - blank=True - ) - class Meta: - verbose_name = 'Диагноз' - verbose_name_plural = 'Диагнозы' + verbose_name = 'Название дисциплины' + verbose_name_plural = 'Названия дисциплин' def __str__(self): - return self.class_name + return self.name -class Gender(BaseUniqueName): +class DisciplineLevel(BaseUniqueName): """ - Модель Пол. + Модель классификация, статусы дисциплин. """ class Meta: - verbose_name = 'Пол' - verbose_name_plural = 'Пол' + verbose_name = 'Классификация/статус дисциплины' + verbose_name_plural = 'Классификация/статусы дисциплин' def __str__(self): return self.name -class Position(BaseUniqueName): +class Discipline(models.Model): """ - Модель Игоровая позиция. + Модель Дисциплина. """ + discipline_name = models.ForeignKey( + DisciplineName, + on_delete=models.CASCADE, + max_length=CLASS_FIELD_LENGTH, + verbose_name=_('Название дисциплины'), + help_text=_('Название дисциплины'), + related_name='disciplines' + ) + discipline_level = models.ForeignKey( + DisciplineLevel, + on_delete=models.CASCADE, + max_length=CLASS_FIELD_LENGTH, + verbose_name=_('Класс/статус'), + help_text=_('Класс/статус'), + related_name='disciplines' + ) + class Meta: - verbose_name = 'Игоровая позиция' - verbose_name_plural = 'Игровые позиции' + verbose_name = 'Дисциплина' + verbose_name_plural = 'Дисциплины' + constraints = [ + models.UniqueConstraint( + name='discipline_name_level_unique', + fields=['discipline_name', 'discipline_level'], + ) + ] def __str__(self): - return self.name + return self.discipline_name.name -class Qualification(BaseUniqueName): +class Nosology(BaseUniqueName): """ - Модель Квалификация. + Модель Нозология. """ class Meta: - verbose_name = 'Квалификация' - verbose_name_plural = 'Квалификации' + verbose_name = 'Нозология' + verbose_name_plural = 'Нозология' def __str__(self): return self.name -class Discipline(BaseUniqueName): +class Diagnosis(BaseUniqueName): """ - Модель Дисциплина. + Модель Диагноз. """ + nosology = models.ForeignKey( + Nosology, + on_delete=models.CASCADE, + max_length=CLASS_FIELD_LENGTH, + verbose_name=_('Нозология'), + help_text=_('Нозология'), + related_name='diagnosis' + ) + class Meta: - verbose_name = 'Дисциплина' - verbose_name_plural = 'Дисциплины' + verbose_name = 'Диагноз' + verbose_name_plural = 'Диагнозы' def __str__(self): return self.name -class City(BaseUniqueName): +class Document(BaseUniqueName): """ - Модель Город. + Модель Документы для загрузки. """ + file = models.FileField( + upload_to='documents', + max_length=CHAR_FIELD_LENGTH + ) + class Meta: - verbose_name = 'Город' - verbose_name_plural = 'Города' + verbose_name = 'Документ' + verbose_name_plural = 'Документы' def __str__(self): return self.name -class Player(BasePerson): +class BasePerson(models.Model): """ - Модель игрока. Связь с командой "многие ко многим" на случай включения - игрока в сборную, помимо основного состава. + Абстрактная модель с базовой персональной информацией. """ - diagnosis = models.ForeignKey( - Diagnosis, - on_delete=models.CASCADE, - related_name='diagnosis', - verbose_name=_('Диагноз'), - help_text=_('Диагноз'), - default=0 + surname = models.CharField( + max_length=CHAR_FIELD_LENGTH, + verbose_name=_('Фамилия'), + help_text=_('Фамилия'), + default=EMPTY_VALUE_DISPLAY ) - gender = models.ForeignKey( - Gender, - on_delete=models.CASCADE, - related_name='gender', - verbose_name=_('Пол'), - help_text=_('Пол'), - default=0 + name = models.CharField( + max_length=CHAR_FIELD_LENGTH, + verbose_name=_('Имя'), + help_text=_('Имя'), + default=EMPTY_VALUE_DISPLAY ) - identification_card = models.TextField( - verbose_name=_('Удостоверение личности'), - help_text=_('Удостоверение личности'), - default=0 + patronymic = models.CharField( + max_length=CHAR_FIELD_LENGTH, + blank=True, + verbose_name=_('Отчество'), + help_text=_('Отчество'), + default=EMPTY_VALUE_DISPLAY ) - class Meta(BasePerson.Meta): - default_related_name = 'players' - verbose_name = 'Игрок' - verbose_name_plural = 'Игроки' - constraints = [ - models.UniqueConstraint( - name='player_unique', - fields=['name', 'surname', 'patronymic', 'date_of_birth'] - ) - ] + class Meta: + ordering = ('surname', 'name', 'patronymic') + abstract = True def __str__(self): return ' '.join([self.surname, self.name, self.patronymic]) -class Trainer(BasePerson): +class StaffMember(BasePerson): """ - Модель Тренер. + Модель сотрудник. """ - description = models.TextField( - verbose_name=_('Описание'), - help_text=_('Описание') + phone = models.CharField( + max_length=CHAR_FIELD_LENGTH, + blank=True, + default=EMPTY_VALUE_DISPLAY, + verbose_name=_('Номер телефона'), + help_text=_('Номер телефона') ) class Meta: - verbose_name = 'Тренер' - verbose_name_plural = 'Тренеры' + verbose_name = 'Сотрудник' + verbose_name_plural = 'Сотрудники' def __str__(self): return ' '.join([self.surname, self.name, self.patronymic]) -class Team(models.Model): +class StaffTeamMember(models.Model): """ - Модель команды. + Модель сотрудник команды. """ - name = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Название'), - help_text=_('Название') + staff_member = models.ForeignKey( + StaffMember, + on_delete=models.CASCADE, + verbose_name=_('Сотрудник'), + help_text=_('Сотрудник') + ) + staff_position = models.CharField( + max_length=CHAR_FIELD_LENGTH, + choices=STAFF_POSITION_CHOICES, + default=EMPTY_VALUE_DISPLAY, + verbose_name=_('Статус сотрудника'), + help_text=_('Статус сотрудника') + ) + qualification = models.CharField( + max_length=CHAR_FIELD_LENGTH, + default=EMPTY_VALUE_DISPLAY, + blank=True, + verbose_name=_('Квалификация'), + help_text=_('Квалификация') + ) + notes = models.TextField( + default=EMPTY_VALUE_DISPLAY, + verbose_name=_('Описание'), + help_text=_('Описание'), + blank=True ) + + class Meta: + verbose_name = 'Сотрудник команды' + verbose_name_plural = 'Сотрудники команды' + + def __str__(self): + return ' '.join([ + self.staff_member.surname, + self.staff_member.name, + self.staff_member.patronymic + ]) + + +class Team(BaseUniqueName): + """ + Модель команды. + """ city = models.ForeignKey( - to=City, - on_delete=models.SET_NULL, - blank=True, - null=True, + City, + on_delete=models.CASCADE, verbose_name=_('Город откуда команда'), help_text=_('Город откуда команда') ) - discipline = models.ForeignKey( - to=Discipline, - on_delete=models.SET_NULL, - blank=True, - null=True, + staff_team_member = models.ForeignKey( + StaffTeamMember, + on_delete=models.CASCADE, + verbose_name=_('Сотрудник команды'), + help_text=_('Сотрудник команды') + ) + discipline_name = models.ForeignKey( + DisciplineName, + on_delete=models.CASCADE, verbose_name=_('Дисциплина команды'), help_text=_('Дисциплина команды') ) - composition = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Состав'), - help_text=_('Состав'), - default=EMPTY_VALUE_DISPLAY - ) - age = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Возраст'), - help_text=_('Возраст'), - default=EMPTY_VALUE_DISPLAY - ) + # TODO curator = User (model) class Meta: default_related_name = 'teams' @@ -253,7 +288,7 @@ class Meta: constraints = [ models.UniqueConstraint( name='team_city_unique', - fields=['name', 'city', 'discipline'], + fields=['name', 'city', 'discipline_name'], ) ] @@ -263,78 +298,71 @@ def __str__(self): return self.name -class TrainerTeam(models.Model): +class Player(BasePerson): """ - Модель тренер - команда. + Модель игрока. Связь с командой "многие ко многим" на случай включения + игрока в сборную, помимо основного состава. """ - trainer = models.ForeignKey( - to=Trainer, - on_delete=models.CASCADE, - verbose_name=_('Тренер команды'), - help_text=_('Тренер команды') - ) - team = models.ForeignKey( - to=Team, - on_delete=models.CASCADE, - verbose_name=_('Команда'), - help_text=_('Команда') + diagnosis = models.ForeignKey( + Diagnosis, + on_delete=models.SET_NULL, + null=True, + related_name='player_diagnosis', + verbose_name=_('Диагноз'), + help_text=_('Диагноз'), ) - - class Meta: - default_related_name = 'trainer_teams' - verbose_name = 'Тренер --> команда' - verbose_name_plural = 'Тренер --> команды' - constraints = [ - models.UniqueConstraint( - name='trainer_teams_unique', - fields=['trainer', 'team'] - ) - ] - - def __str__(self): - return str(self.trainer.id) - - -class PlayerTeam(models.Model): - """ - Связь "многие ко многим" игрока с командой с добавлением данных игрока - в этой команде. - """ - player = models.ForeignKey( - to=Player, - related_name='player_teams', - on_delete=models.CASCADE, - verbose_name=_('Игрок'), - help_text=_('Игрок') - + discipline = models.ForeignKey( + Discipline, + on_delete=models.SET_NULL, + null=True, + related_name='player_disciplines', + verbose_name=_('Дисциплина'), + help_text=_('Дисциплина'), ) - team = models.ForeignKey( - to=Team, + team = models.ManyToManyField( + Team, related_name='team_players', - on_delete=models.CASCADE, verbose_name=_('Команда'), help_text=_('Команда') ) - position = models.ForeignKey( - to=Position, - on_delete=models.SET_NULL, + document = models.ForeignKey( + Document, + on_delete=models.CASCADE, + related_name='player_documemts', + verbose_name=_('Документ'), + help_text=_('Документ'), + default=EMPTY_VALUE_DISPLAY, blank=True, - null=True, - verbose_name=_('Позиция игрока'), - help_text=_('Позиция игрока') + null=True ) - qualification = models.ForeignKey( - to=Qualification, - on_delete=models.SET_NULL, - blank=True, - null=True, - verbose_name=_('Квалификация игрока'), - help_text=_('Квалификация игрока') + birthday = models.DateField( + verbose_name=_('Дата рождения'), + help_text=_('Дата рождения') + ) + gender = models.CharField( + max_length=CHAR_FIELD_LENGTH, + choices=GENDER_CHOICES, + default=EMPTY_VALUE_DISPLAY, + verbose_name=_('Пол'), + help_text=_('Пол') + ) + level_revision = models.TextField( + verbose_name=_('Уровень ревизии'), + help_text=_('Уровень ревизии'), + default=EMPTY_VALUE_DISPLAY, + blank=True ) - number = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Номер игорока'), - help_text=_('Номер игорока') + position = models.CharField( + max_length=CHAR_FIELD_LENGTH, + choices=PLAYER_POSITION_CHOICES, + default=EMPTY_VALUE_DISPLAY, + verbose_name=_('Игровая позиция'), + help_text=_('Игровая позиция') + ) + number = models.IntegerField( + default=DEFAULT_VALUE, + verbose_name=_('Номер игрока'), + help_text=_('Номер игрока') ) is_captain = models.BooleanField( default=False, @@ -346,88 +374,35 @@ class PlayerTeam(models.Model): verbose_name=_('Ассистент'), help_text=_('Ассистент') ) - - class Meta: - verbose_name = 'Игрок команды' - verbose_name_plural = 'Игроки команды' - - def __str__(self): - return str(self.player.id) - - -class Competition(BaseUniqueName): - """ - Модель Соревнования. - """ - city = models.ForeignKey( - to=City, - on_delete=models.SET_NULL, - blank=True, - null=True, - verbose_name=_('Город'), - help_text=_('Город') - ) - number = models.CharField( - max_length=NAME_FIELD_LENGTH, - verbose_name=_('Номер соревнований'), - help_text=_('Номер соревнований') - ) - date = models.DateField( - verbose_name=_('Дата соревнований'), - help_text=_('Дата соревнований') - ) - duration = models.IntegerField( - default=0, - verbose_name=_('Длительность'), - help_text=_('Длительность') - ) - is_active = models.BooleanField( - default=True, - verbose_name=_('Активно'), - help_text=_('Активно') + identity_document = models.TextField( + verbose_name=_('Удостоверение личности'), + help_text=_('Удостоверение личности'), + default=EMPTY_VALUE_DISPLAY, + blank=True ) - class Meta: - verbose_name = 'Соревнование' - verbose_name_plural = 'Соревнования' + class Meta(BasePerson.Meta): + default_related_name = 'players' + verbose_name = 'Игрок' + verbose_name_plural = 'Игроки' constraints = [ models.UniqueConstraint( - name='competitions_unique', - fields=['city', 'number', 'date'] - ) - ] - - def __str__(self): - return str(self.city.id) - - -class TeamCompetition(models.Model): - """ - Модель команда - соревнование. - """ - team = models.ForeignKey( - to=Team, - on_delete=models.CASCADE, - verbose_name=_('Команда'), - help_text=_('Команда') - ) - competition = models.ForeignKey( - to=Competition, - on_delete=models.CASCADE, - verbose_name=_('Соревнование'), - help_text=_('Соревнование') - ) - - class Meta: - default_related_name = 'team_competitions' - verbose_name = 'Соревнование --> команда' - verbose_name_plural = 'Совревнования --> команды' - constraints = [ + name='player_unique', + fields=[ + 'name', + 'surname', + 'patronymic', + 'birthday', + ] + ), models.UniqueConstraint( - name='competition_teams_unique', - fields=['team', 'competition'] + name='player_position_number_unique', + fields=[ + 'position', + 'number' + ] ) ] def __str__(self): - return str(self.team.id) + return ' '.join([self.surname, self.name, self.patronymic])