Merge branch 'master' of gitlab.prodcontest.ru:team-15/project

This commit is contained in:
ITQ
2025-03-01 18:19:59 +03:00
33 changed files with 740 additions and 67 deletions
@@ -0,0 +1,49 @@
# Generated by Django 5.1.6 on 2025-03-01 14:46
import tinymce.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('competition', '0003_remove_competition_tasks'),
]
operations = [
migrations.AlterField(
model_name='competition',
name='description',
field=tinymce.models.HTMLField(verbose_name='описание'),
),
migrations.AlterField(
model_name='competition',
name='end_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='дедлайн участия'),
),
migrations.AlterField(
model_name='competition',
name='image_url',
field=models.FileField(blank=True, null=True, upload_to='', verbose_name='изображение соревнования'),
),
migrations.AlterField(
model_name='competition',
name='participation_type',
field=models.CharField(choices=[('edu', 'Образовательный'), ('competitive', 'Соревновательный')], max_length=11, verbose_name='тип соревнования'),
),
migrations.AlterField(
model_name='competition',
name='start_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='дедлайн участия'),
),
migrations.AlterField(
model_name='competition',
name='title',
field=models.CharField(max_length=100, verbose_name='аазвание'),
),
migrations.AlterField(
model_name='competition',
name='type',
field=models.CharField(choices=[('solo', 'Индивидуальный')], max_length=10, verbose_name='тип участия'),
),
]
+10 -7
View File
@@ -1,6 +1,7 @@
from datetime import datetime
from django.db import models
from tinymce.models import HTMLField
from apps.core.models import BaseModel
from apps.user.models import User
@@ -17,29 +18,29 @@ class Competition(BaseModel):
def image_url_upload_to(instance, filename):
return f"/competitions/{instance.id}/image"
title = models.CharField(max_length=100, verbose_name="Название")
description = models.TextField(verbose_name="Описание")
title = models.CharField(max_length=100, verbose_name="название")
description = models.TextField(verbose_name="описание")
image_url = models.FileField(
verbose_name="Изображение соревнования",
verbose_name="изображение соревнования",
null=True,
blank=True,
upload_to=image_url_upload_to,
)
end_date = models.DateTimeField(
verbose_name="Дедлайн участия", null=True, blank=True
verbose_name="дедлайн участия", null=True, blank=True
)
start_date = models.DateTimeField(
verbose_name="Дедлайн участия", null=True, blank=True
verbose_name="дедлайн участия", null=True, blank=True
)
type = models.CharField(
max_length=10,
choices=CompetitionType.choices,
verbose_name="Тип участия",
verbose_name="тип участия",
)
participation_type = models.CharField(
max_length=11,
choices=CompetitionParticipationType.choices,
verbose_name="Тип соревнования",
verbose_name="тип соревнования",
)
participants = models.ManyToManyField(
User, related_name="participants", blank=True, editable=False
@@ -48,6 +49,8 @@ class Competition(BaseModel):
def __str__(self):
return self.title
class Meta:
verbose_name = "соревнование"
verbose_name_plural = "соревнования"
@@ -8,7 +8,7 @@ from django.core.management.base import BaseCommand
from django.utils import timezone
from apps.competition.models import Competition, State
from apps.task.models import CompetetionTaskSumbission, CompetitionTask
from apps.task.models import CompetitionTaskSubmission, CompetitionTask
from apps.user.models import User, UserRole
@@ -105,7 +105,7 @@ class Command(BaseCommand):
b"Submission content",
name=f"submission_{uuid.uuid4().hex}.txt",
)
submission = CompetetionTaskSumbission.objects.create(
submission = CompetitionTaskSubmission.objects.create(
user=user,
task=task,
earned_points=random.randint(
@@ -0,0 +1,26 @@
# Generated by Django 5.1.6 on 2025-03-01 14:47
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('review', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Review',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('state', models.CharField(choices=[('not_checked', 'Not Checked'), ('checking', 'Checking'), ('checked', 'Checked')], max_length=11)),
('reviewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review.reviewer')),
],
options={
'abstract': False,
},
),
]
@@ -0,0 +1,20 @@
# Generated by Django 5.1.6 on 2025-03-01 14:47
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('review', '0002_review'),
('task', '0005_alter_competitiontask_description_and_more'),
]
operations = [
migrations.AddField(
model_name='review',
name='submission',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='task.competitiontasksubmission'),
),
]
+12
View File
@@ -1,6 +1,7 @@
from django.db import models
from apps.core.models import BaseModel
from apps.task.models import CompetitionTaskSubmission
class Reviewer(BaseModel):
@@ -8,3 +9,14 @@ class Reviewer(BaseModel):
surname = models.CharField(max_length=100)
token = models.CharField(max_length=100)
class Review(BaseModel):
class ReviewStatusChoices(models.TextChoices):
NOT_CHECKED = "not_checked"
CHECKING = "checking"
CHECKED = "checked"
reviewer = models.ForeignKey(Reviewer, on_delete=models.CASCADE)
submission = models.ForeignKey(CompetitionTaskSubmission, on_delete=models.CASCADE)
state = models.CharField(choices=ReviewStatusChoices.choices, max_length=11)
@@ -38,8 +38,8 @@ class Migration(migrations.Migration):
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('status', models.CharField(choices=[('sent', 'Sent'), ('checking', 'Checking'), ('checked', 'Checked')], default='sent', max_length=8)),
('content', models.FileField(upload_to=apps.task.models.CompetetionTaskSumbission.submission_content_upload_to)),
('stdout', models.FileField(blank=True, null=True, upload_to=apps.task.models.CompetetionTaskSumbission.submission_stdout_upload_to)),
('content', models.FileField(upload_to=apps.task.models.CompetitionTaskSubmission.submission_content_upload_to)),
('stdout', models.FileField(blank=True, null=True, upload_to=apps.task.models.CompetitionTaskSubmission.submission_stdout_upload_to)),
('result', models.JSONField(blank=True, default=None, null=True)),
('earned_points', models.IntegerField()),
('timestamp', models.DateTimeField(auto_now_add=True)),
@@ -0,0 +1,19 @@
# Generated by Django 5.1.6 on 2025-03-01 12:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('review', '0001_initial'),
('task', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='competetiontasksumbission',
name='reviewers',
field=models.ManyToManyField(blank=True, related_name='reviewers', to='review.reviewer'),
),
]
@@ -0,0 +1,14 @@
# Generated by Django 5.1.6 on 2025-03-01 14:39
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('task', '0002_competetiontasksumbission_reviewers'),
('task', '0003_competitiontask_max_attemps_and_more'),
]
operations = [
]
@@ -0,0 +1,48 @@
# Generated by Django 5.1.6 on 2025-03-01 14:47
import apps.task.models
import django.db.models.deletion
import tinymce.models
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('task', '0004_merge_20250301_1739'),
('user', '0002_alter_user_email_alter_user_password_and_more'),
]
operations = [
migrations.AlterField(
model_name='competitiontask',
name='description',
field=tinymce.models.HTMLField(max_length=300, verbose_name='описание'),
),
migrations.AlterField(
model_name='competitiontask',
name='max_attemps',
field=models.PositiveSmallIntegerField(),
),
migrations.CreateModel(
name='CompetitionTaskSubmission',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('status', models.CharField(choices=[('sent', 'Sent'), ('checking', 'Checking'), ('checked', 'Checked')], default='sent', max_length=8)),
('content', models.FileField(upload_to=apps.task.models.CompetitionTaskSubmission.submission_content_upload_to)),
('stdout', models.FileField(blank=True, null=True, upload_to=apps.task.models.CompetitionTaskSubmission.submission_stdout_upload_to)),
('result', models.JSONField(blank=True, default=None, null=True)),
('earned_points', models.IntegerField()),
('timestamp', models.DateTimeField(auto_now_add=True)),
('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='task.competitiontask')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='user.user')),
],
options={
'abstract': False,
},
),
migrations.DeleteModel(
name='CompetetionTaskSumbission',
),
]
+4 -3
View File
@@ -1,6 +1,7 @@
from uuid import uuid4
from django.db import models
from tinymce.models import HTMLField
from apps.competition.models import Competition
from apps.core.models import BaseModel
@@ -19,8 +20,8 @@ class CompetitionTask(BaseModel):
competition = models.ForeignKey(Competition, on_delete=models.CASCADE)
title = models.CharField(verbose_name="заголовок", max_length=50)
description = models.TextField(verbose_name="описание", max_length=300)
max_attemps = models.PositiveSmallIntegerField(default=0)
description = HTMLField(verbose_name="описание", max_length=300)
max_attemps = models.PositiveSmallIntegerField()
type = models.CharField(
choices=CompetitionTaskType, max_length=8, verbose_name="тип проверки"
)
@@ -63,7 +64,7 @@ class CompetitionTask(BaseModel):
verbose_name_plural = "задания"
class CompetetionTaskSumbission(BaseModel):
class CompetitionTaskSubmission(BaseModel):
class StatusChoices(models.TextChoices):
SENT = "sent"
CHECKING = "checking"
+9
View File
@@ -0,0 +1,9 @@
from django.contrib import admin
from apps.user.models import User
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ("email", "username")
search_fields = ("id", "email", "username")
+1
View File
@@ -5,3 +5,4 @@ class UsersConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "apps.user"
label = "user"
verbose_name = "Пользователи"
@@ -0,0 +1,28 @@
# Generated by Django 5.1.6 on 2025-03-01 14:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='user',
name='email',
field=models.EmailField(max_length=254, unique=True, verbose_name='почта'),
),
migrations.AlterField(
model_name='user',
name='password',
field=models.TextField(verbose_name='пароль'),
),
migrations.AlterField(
model_name='user',
name='username',
field=models.SlugField(unique=True, verbose_name='юзернейм'),
),
]
+10 -3
View File
@@ -1,4 +1,5 @@
from django.db import models
from django.contrib.auth.hashers import check_password, make_password
from apps.core.models import BaseModel
@@ -9,9 +10,15 @@ class UserRole(models.Choices):
class User(BaseModel):
email = models.EmailField(unique=True, verbose_name="Почта")
username = models.SlugField(unique=True, verbose_name="Юзернейм")
password = models.TextField(verbose_name="Пароль")
email = models.EmailField(unique=True, verbose_name="почта")
username = models.SlugField(unique=True, verbose_name="юзернейм")
password = models.TextField(verbose_name="пароль")
def make_password(self):
return make_password(self.password)
def check_password(self, password):
return check_password(self.password, password)
status = models.CharField(
max_length=10, choices=UserRole, default="student"