mirror of
https://gitlab.com/megazordpobeda/DataRush.git
synced 2026-05-23 06:17:10 +00:00
feat: added task submission logic
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 21:27
|
||||
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Competition',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(max_length=100, verbose_name='Название')),
|
||||
('description', models.TextField(verbose_name='Описание')),
|
||||
('image_url', models.FileField(blank=True, null=True, upload_to='', verbose_name='Изображение соревнования')),
|
||||
('end_date', models.DateTimeField(blank=True, null=True, verbose_name='Дедлайн участия')),
|
||||
('start_date', models.DateTimeField(blank=True, null=True, verbose_name='Дедлайн участия')),
|
||||
('type', models.CharField(choices=[('solo', 'Solo')], max_length=10, verbose_name='Тип участия')),
|
||||
('participation_type', models.CharField(choices=[('edu', 'Edu'), ('competitive', 'Competitive')], max_length=11, verbose_name='Тип соревнования')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'соревнование',
|
||||
'verbose_name_plural': 'соревнования',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 22:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('competition', '0001_initial'),
|
||||
('user', '0002_user_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='competition',
|
||||
name='participants',
|
||||
field=models.ManyToManyField(related_name='participants', to='user.user'),
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 23:26
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('competition', '0002_competition_participants'),
|
||||
('user', '0003_alter_user_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='State',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('state', models.CharField(choices=[('not_started', 'Not Started'), ('started', 'Started'), ('finished', 'Finished')], max_length=11)),
|
||||
('competition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='competition.competition')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='user.user')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CoreConfig(AppConfig):
|
||||
name = "apps.review"
|
||||
label = "review"
|
||||
@@ -0,0 +1,10 @@
|
||||
from django.db import models
|
||||
|
||||
from apps.core.models import BaseModel
|
||||
|
||||
|
||||
class Reviewer(BaseModel):
|
||||
name = models.CharField(max_length=100)
|
||||
surname = models.CharField(max_length=100)
|
||||
|
||||
token = models.CharField(max_length=100)
|
||||
@@ -1,11 +1,12 @@
|
||||
from random import choice
|
||||
from uuid import uuid4
|
||||
|
||||
from competition.models import Competition
|
||||
from core.models import BaseModel
|
||||
from django.db import models
|
||||
|
||||
from apps.task.validators import ContestTaskCriteriesValidator
|
||||
|
||||
from apps.competition.models import Competition
|
||||
from apps.core.models import BaseModel
|
||||
from apps.user.models import User
|
||||
|
||||
class CompetitionTask(BaseModel):
|
||||
class CompetitionTaskType(models.TextChoices):
|
||||
@@ -14,12 +15,12 @@ class CompetitionTask(BaseModel):
|
||||
REVIEW = "review"
|
||||
|
||||
def answer_file_upload_to(instance, filename) -> str:
|
||||
return f"/tasks/{instance.id}/answer/{uuid4}"
|
||||
return f"/tasks/{instance.id}/answer/{uuid4()}/filename"
|
||||
|
||||
competition = models.ForeignKey(Competition, on_delete=models.CASCADE)
|
||||
title = models.TextField(verbose_name="заголовок", max_length=50)
|
||||
description = models.TextField(verbose_name="описание", max_length=300)
|
||||
type = models.CharField(choices=CompetitionTaskType)
|
||||
type = models.CharField(choices=CompetitionTaskType, max_length=8)
|
||||
|
||||
# only when "input" or "checker" type
|
||||
correct_answer_file = models.FileField(upload_to=answer_file_upload_to)
|
||||
@@ -32,3 +33,26 @@ class CompetitionTask(BaseModel):
|
||||
|
||||
def clean(self):
|
||||
ContestTaskCriteriesValidator()(self)
|
||||
|
||||
|
||||
class CompetetionTaskSumbission(BaseModel):
|
||||
class StatusChoices(models.TextChoices):
|
||||
SENT = "sent"
|
||||
CHECKING = "checking"
|
||||
CHECKED = "checked"
|
||||
|
||||
def submission_content_upload_to(instance, filename) -> str:
|
||||
return f"/submissions/{instance.id}/content"
|
||||
|
||||
def submission_stdout_upload_to(instance, filename) -> str:
|
||||
return f"/submissions/{instance.id}/stdout"
|
||||
|
||||
status = models.CharField(
|
||||
choices=StatusChoices.choices, default=StatusChoices.SENT, max_length=8
|
||||
)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
task = models.ForeignKey(CompetitionTask, on_delete=models.CASCADE)
|
||||
content = models.FileField(upload_to=submission_content_upload_to)
|
||||
stdout = models.FileField(upload_to=submission_stdout_upload_to)
|
||||
result = models.JSONField(default={})
|
||||
timestamp = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 20:46
|
||||
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('email', models.EmailField(max_length=254, unique=True, verbose_name='Почта')),
|
||||
('username', models.SlugField(unique=True, verbose_name='Юзернейм')),
|
||||
('password', models.TextField(verbose_name='Пароль')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'пользователь',
|
||||
'verbose_name_plural': 'пользователи',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 22:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('user', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('student', 'Student'), ('metodist', 'Metodist')], default='student', max_length=10),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-28 22:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('user', '0002_user_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('student', 'Student'), ('metodist', 'Metodist')], default='student', max_length=10),
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user