mirror of
https://gitlab.com/megazordpobeda/DataRush.git
synced 2026-05-23 02:47:10 +00:00
Merge branch 'master' of https://gitlab.prodcontest.ru/team-15/project
This commit is contained in:
@@ -4,8 +4,8 @@ from uuid import UUID
|
|||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from ninja import ModelSchema, Schema
|
from ninja import ModelSchema, Schema
|
||||||
|
|
||||||
from apps.review.models import Reviewer
|
from apps.review.models import Reviewer, Review
|
||||||
from apps.task.models import CompetetionTaskSumbission
|
from apps.task.models import CompetitionTaskSubmission
|
||||||
|
|
||||||
|
|
||||||
class PingOut(Schema):
|
class PingOut(Schema):
|
||||||
@@ -25,13 +25,13 @@ class SubmissionOut(ModelSchema):
|
|||||||
status: Literal["sent", "checking", "checked"]
|
status: Literal["sent", "checking", "checked"]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CompetetionTaskSumbission
|
model = CompetitionTaskSubmission
|
||||||
exclude = ("user",)
|
exclude = ("user",)
|
||||||
|
|
||||||
|
|
||||||
class SubmissionsOut(Schema):
|
class SubmissionsOut(Schema):
|
||||||
submissions: list[SubmissionOut] = []
|
submissions: list = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def resolve_submissions(self, context: HttpRequest) -> list[SubmissionOut]:
|
def resolve_submissions(self, context) -> list[SubmissionOut]:
|
||||||
return list(CompetetionTaskSumbission.objects.all())
|
return list(Review.objects.filter(reviewer=context.get("request").auth))
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
|
import logging
|
||||||
from http import HTTPStatus as status
|
from http import HTTPStatus as status
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from ninja import Router
|
from ninja import Router
|
||||||
|
|
||||||
from api.v1 import schemas as global_schemas
|
from api.v1 import schemas as global_schemas
|
||||||
from api.v1.review import schemas
|
from api.v1.review import schemas
|
||||||
|
from api.v1.task.schemas import TaskSubmissionIn
|
||||||
|
from apps.task.models import CompetitionTaskSubmission
|
||||||
|
|
||||||
router = Router(tags=["review"])
|
router = Router(tags=["review"])
|
||||||
|
|
||||||
@@ -16,7 +21,7 @@ router = Router(tags=["review"])
|
|||||||
},
|
},
|
||||||
description="Список отправок, на проверку которых назначен ревьюер"
|
description="Список отправок, на проверку которых назначен ревьюер"
|
||||||
)
|
)
|
||||||
def get_submissions(request: HttpRequest, token) -> tuple[status, schemas.SubmissionsOut]:
|
def get_submissions(request: HttpRequest, token: str) -> tuple[status, schemas.SubmissionsOut]:
|
||||||
return status.OK, schemas.SubmissionsOut()
|
return status.OK, schemas.SubmissionsOut()
|
||||||
|
|
||||||
|
|
||||||
@@ -30,3 +35,13 @@ def get_submissions(request: HttpRequest, token) -> tuple[status, schemas.Submis
|
|||||||
)
|
)
|
||||||
def get_reviewer_profile(request: HttpRequest, token: str):
|
def get_reviewer_profile(request: HttpRequest, token: str):
|
||||||
return status.OK, request.auth
|
return status.OK, request.auth
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"{token}/submissions/{submition_id}",
|
||||||
|
response={
|
||||||
|
status.OK: schemas.SubmissionOut,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
def get_submission(request: HttpRequest, token: str, submition_id: UUID) -> tuple[status, schemas.SubmissionsOut]:
|
||||||
|
submission = get_object_or_404(CompetitionTaskSubmission, id=submition_id)
|
||||||
|
return status.OK, submission
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from api.v1.task.schemas import (
|
|||||||
)
|
)
|
||||||
from apps.competition.models import State
|
from apps.competition.models import State
|
||||||
from apps.task.models import (
|
from apps.task.models import (
|
||||||
CompetetionTaskSumbission,
|
CompetitionTaskSubmission,
|
||||||
Competition,
|
Competition,
|
||||||
CompetitionTask,
|
CompetitionTask,
|
||||||
)
|
)
|
||||||
@@ -96,23 +96,23 @@ def submit_task(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if task.type == CompetitionTask.CompetitionTaskType.INPUT:
|
if task.type == CompetitionTask.CompetitionTaskType.INPUT:
|
||||||
CompetetionTaskSumbission.objects.create(
|
CompetitionTaskSubmission.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
task=task,
|
task=task,
|
||||||
status=CompetetionTaskSumbission.StatusChoices.CHECKED,
|
status=CompetitionTaskSubmission.StatusChoices.CHECKED,
|
||||||
result={"correct": submission.content == task.answer_file_path},
|
result={"correct": submission.content == task.answer_file_path},
|
||||||
)
|
)
|
||||||
if task.type == CompetitionTask.CompetitionTaskType.REVIEW:
|
if task.type == CompetitionTask.CompetitionTaskType.REVIEW:
|
||||||
CompetetionTaskSumbission.objects.create(
|
CompetitionTaskSubmission.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
task=task,
|
task=task,
|
||||||
status=CompetetionTaskSumbission.StatusChoices.SENT,
|
status=CompetitionTaskSubmission.StatusChoices.SENT,
|
||||||
)
|
)
|
||||||
if task.type == CompetitionTask.CompetitionTaskType.CHECKER:
|
if task.type == CompetitionTask.CompetitionTaskType.CHECKER:
|
||||||
CompetetionTaskSumbission.objects.create(
|
CompetitionTaskSubmission.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
task=task,
|
task=task,
|
||||||
status=CompetetionTaskSumbission.StatusChoices.CHECKING,
|
status=CompetitionTaskSubmission.StatusChoices.CHECKING,
|
||||||
)
|
)
|
||||||
|
|
||||||
return TaskSubmissionOut(id=CompetetionTaskSumbission.id)
|
return TaskSubmissionOut(id=CompetitionTaskSubmission.id)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ router = Router(tags=["user"])
|
|||||||
)
|
)
|
||||||
def sign_up(request, data: RegisterSchema):
|
def sign_up(request, data: RegisterSchema):
|
||||||
user = User(**data.dict())
|
user = User(**data.dict())
|
||||||
|
user.password = user.make_password()
|
||||||
user.full_clean()
|
user.full_clean()
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ def sign_in(request, data: LoginSchema):
|
|||||||
user = User.objects.filter(email=data.email).first()
|
user = User.objects.filter(email=data.email).first()
|
||||||
if not user:
|
if not user:
|
||||||
raise AuthenticationError
|
raise AuthenticationError
|
||||||
if user.password != data.password:
|
if not user.check_password(data.password):
|
||||||
raise AuthenticationError
|
raise AuthenticationError
|
||||||
|
|
||||||
token = BearerAuth.generate_jwt(user)
|
token = BearerAuth.generate_jwt(user)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 5.1.6 on 2025-03-01 13:49
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('competition', '0002_competition_tasks_alter_competition_participants_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='competition',
|
||||||
|
name='tasks',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from tinymce.models import HTMLField
|
||||||
|
|
||||||
from apps.core.models import BaseModel
|
from apps.core.models import BaseModel
|
||||||
from apps.user.models import User
|
from apps.user.models import User
|
||||||
@@ -14,26 +15,26 @@ class Competition(BaseModel):
|
|||||||
EDU = "edu", "Образовательный"
|
EDU = "edu", "Образовательный"
|
||||||
COMPETITIVE = "competitive", "Соревновательный"
|
COMPETITIVE = "competitive", "Соревновательный"
|
||||||
|
|
||||||
title = models.CharField(max_length=100, verbose_name="Название")
|
title = models.CharField(max_length=100, verbose_name="аазвание")
|
||||||
description = models.TextField(verbose_name="Описание")
|
description = HTMLField(verbose_name="описание")
|
||||||
image_url = models.FileField(
|
image_url = models.FileField(
|
||||||
verbose_name="Изображение соревнования", null=True, blank=True
|
verbose_name="изображение соревнования", null=True, blank=True
|
||||||
)
|
)
|
||||||
end_date = models.DateTimeField(
|
end_date = models.DateTimeField(
|
||||||
verbose_name="Дедлайн участия", null=True, blank=True
|
verbose_name="дедлайн участия", null=True, blank=True
|
||||||
)
|
)
|
||||||
start_date = models.DateTimeField(
|
start_date = models.DateTimeField(
|
||||||
verbose_name="Дедлайн участия", null=True, blank=True
|
verbose_name="дедлайн участия", null=True, blank=True
|
||||||
)
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
choices=CompetitionType.choices,
|
choices=CompetitionType.choices,
|
||||||
verbose_name="Тип участия",
|
verbose_name="тип участия",
|
||||||
)
|
)
|
||||||
participation_type = models.CharField(
|
participation_type = models.CharField(
|
||||||
max_length=11,
|
max_length=11,
|
||||||
choices=CompetitionParticipationType.choices,
|
choices=CompetitionParticipationType.choices,
|
||||||
verbose_name="Тип соревнования",
|
verbose_name="тип соревнования",
|
||||||
)
|
)
|
||||||
participants = models.ManyToManyField(User, related_name="participants", blank=True,
|
participants = models.ManyToManyField(User, related_name="participants", blank=True,
|
||||||
editable=False)
|
editable=False)
|
||||||
@@ -41,6 +42,8 @@ class Competition(BaseModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "соревнование"
|
verbose_name = "соревнование"
|
||||||
verbose_name_plural = "соревнования"
|
verbose_name_plural = "соревнования"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from django.core.management.base import BaseCommand
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from apps.competition.models import Competition, State
|
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
|
from apps.user.models import User, UserRole
|
||||||
|
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ class Command(BaseCommand):
|
|||||||
b"Submission content",
|
b"Submission content",
|
||||||
name=f"submission_{uuid.uuid4().hex}.txt",
|
name=f"submission_{uuid.uuid4().hex}.txt",
|
||||||
)
|
)
|
||||||
submission = CompetetionTaskSumbission.objects.create(
|
submission = CompetitionTaskSubmission.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
task=task,
|
task=task,
|
||||||
earned_points=random.randint(
|
earned_points=random.randint(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from apps.core.models import BaseModel
|
from apps.core.models import BaseModel
|
||||||
|
from apps.task.models import CompetitionTaskSubmission
|
||||||
|
|
||||||
|
|
||||||
class Reviewer(BaseModel):
|
class Reviewer(BaseModel):
|
||||||
@@ -8,3 +9,14 @@ class Reviewer(BaseModel):
|
|||||||
surname = models.CharField(max_length=100)
|
surname = models.CharField(max_length=100)
|
||||||
|
|
||||||
token = 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=[
|
fields=[
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
('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)),
|
('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)),
|
('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.CompetetionTaskSumbission.submission_stdout_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)),
|
('result', models.JSONField(blank=True, default=None, null=True)),
|
||||||
('earned_points', models.IntegerField()),
|
('earned_points', models.IntegerField()),
|
||||||
('timestamp', models.DateTimeField(auto_now_add=True)),
|
('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,51 @@
|
|||||||
|
# Generated by Django 5.1.6 on 2025-03-01 13:49
|
||||||
|
|
||||||
|
import apps.task.models
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('competition', '0003_remove_competition_tasks'),
|
||||||
|
('task', '0002_alter_competitiontask_options_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='max_attemps',
|
||||||
|
field=models.PositiveSmallIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='answer_file_path',
|
||||||
|
field=models.TextField(blank=True, default='stdout', null=True, verbose_name='куда сохранять решения'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='competition',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='competition.competition'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='correct_answer_file',
|
||||||
|
field=models.FileField(blank=True, null=True, upload_to=apps.task.models.CompetitionTask.answer_file_upload_to, verbose_name='файл с правильным ответом'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='criteries',
|
||||||
|
field=models.JSONField(blank=True, null=True, verbose_name='критерии'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='title',
|
||||||
|
field=models.CharField(max_length=50, verbose_name='заголовок'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='competitiontask',
|
||||||
|
name='type',
|
||||||
|
field=models.CharField(choices=[('input', 'Ввод правильного ответа'), ('checker', 'Вывод кода'), ('review', 'Ручная')], max_length=8, verbose_name='тип проверки'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from tinymce.models import HTMLField
|
||||||
|
|
||||||
from apps.competition.models import Competition
|
from apps.competition.models import Competition
|
||||||
from apps.core.models import BaseModel
|
from apps.core.models import BaseModel
|
||||||
@@ -19,7 +20,7 @@ class CompetitionTask(BaseModel):
|
|||||||
|
|
||||||
competition = models.ForeignKey(Competition, on_delete=models.CASCADE)
|
competition = models.ForeignKey(Competition, on_delete=models.CASCADE)
|
||||||
title = models.CharField(verbose_name="заголовок", max_length=50)
|
title = models.CharField(verbose_name="заголовок", max_length=50)
|
||||||
description = models.TextField(verbose_name="описание", max_length=300)
|
description = HTMLField(verbose_name="описание", max_length=300)
|
||||||
max_attemps = models.PositiveSmallIntegerField()
|
max_attemps = models.PositiveSmallIntegerField()
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
choices=CompetitionTaskType, max_length=8, verbose_name="тип проверки"
|
choices=CompetitionTaskType, max_length=8, verbose_name="тип проверки"
|
||||||
@@ -50,14 +51,6 @@ class CompetitionTask(BaseModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name="критерии",
|
verbose_name="критерии",
|
||||||
default=lambda: [
|
|
||||||
{
|
|
||||||
"name": "CHANGE ME",
|
|
||||||
"slug": "CHANGE ME",
|
|
||||||
"max_value": 0,
|
|
||||||
"min_value": 0,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@@ -71,7 +64,7 @@ class CompetitionTask(BaseModel):
|
|||||||
verbose_name_plural = "задания"
|
verbose_name_plural = "задания"
|
||||||
|
|
||||||
|
|
||||||
class CompetetionTaskSumbission(BaseModel):
|
class CompetitionTaskSubmission(BaseModel):
|
||||||
class StatusChoices(models.TextChoices):
|
class StatusChoices(models.TextChoices):
|
||||||
SENT = "sent"
|
SENT = "sent"
|
||||||
CHECKING = "checking"
|
CHECKING = "checking"
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -5,3 +5,4 @@ class UsersConfig(AppConfig):
|
|||||||
default_auto_field = "django.db.models.BigAutoField"
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = "apps.user"
|
name = "apps.user"
|
||||||
label = "user"
|
label = "user"
|
||||||
|
verbose_name = "Пользователи"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.contrib.auth.hashers import check_password, make_password
|
||||||
|
|
||||||
from apps.core.models import BaseModel
|
from apps.core.models import BaseModel
|
||||||
|
|
||||||
@@ -9,9 +10,15 @@ class UserRole(models.Choices):
|
|||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
email = models.EmailField(unique=True, verbose_name="Почта")
|
email = models.EmailField(unique=True, verbose_name="почта")
|
||||||
username = models.SlugField(unique=True, verbose_name="Юзернейм")
|
username = models.SlugField(unique=True, verbose_name="юзернейм")
|
||||||
password = models.TextField(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(
|
status = models.CharField(
|
||||||
max_length=10, choices=UserRole, default="student"
|
max_length=10, choices=UserRole, default="student"
|
||||||
|
|||||||
@@ -441,6 +441,7 @@ INSTALLED_APPS = [
|
|||||||
"django_guid",
|
"django_guid",
|
||||||
"ninja",
|
"ninja",
|
||||||
"minio_storage",
|
"minio_storage",
|
||||||
|
"tinymce",
|
||||||
# Internal apps
|
# Internal apps
|
||||||
"apps.core",
|
"apps.core",
|
||||||
"apps.user",
|
"apps.user",
|
||||||
@@ -449,6 +450,22 @@ INSTALLED_APPS = [
|
|||||||
"apps.task",
|
"apps.task",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# tinymce
|
||||||
|
TINYMCE_DEFAULT_CONFIG = {
|
||||||
|
"theme": "silver",
|
||||||
|
"height": 500,
|
||||||
|
"menubar": False,
|
||||||
|
"plugins": "advlist,autolink,lists,link,image,charmap,print,preview,anchor,"
|
||||||
|
"searchreplace,visualblocks,code,fullscreen,insertdatetime,media,table,paste,"
|
||||||
|
"code,help,wordcount",
|
||||||
|
"toolbar": "undo redo | formatselect | "
|
||||||
|
"bold italic backcolor | alignleft aligncenter "
|
||||||
|
"alignright alignjustify | bullist numlist outdent indent | "
|
||||||
|
"removeformat | help",
|
||||||
|
"skin": "oxide-dark",
|
||||||
|
"content_css": "dark"
|
||||||
|
}
|
||||||
|
|
||||||
# GUID
|
# GUID
|
||||||
|
|
||||||
DJANGO_GUID = {
|
DJANGO_GUID = {
|
||||||
@@ -466,6 +483,10 @@ DJANGO_GUID = {
|
|||||||
|
|
||||||
LANGUAGE_COOKIE_AGE = 31449600
|
LANGUAGE_COOKIE_AGE = 31449600
|
||||||
|
|
||||||
|
PASSWORD_HASHERS = [
|
||||||
|
"django.contrib.auth.hashers.Argon2PasswordHasher",
|
||||||
|
]
|
||||||
|
|
||||||
LANGUAGE_COOKIE_DOMAIN = None
|
LANGUAGE_COOKIE_DOMAIN = None
|
||||||
|
|
||||||
LANGUAGE_COOKIE_HTTPONLY = False
|
LANGUAGE_COOKIE_HTTPONLY = False
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ admin.site.index_title = "DataRush"
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
# tinymce
|
||||||
|
path('tinymce/', include('tinymce.urls')),
|
||||||
# Admin urls
|
# Admin urls
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
# API urls
|
# API urls
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ version = "0.1.0"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10,<3.12"
|
requires-python = ">=3.10,<3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"argon2-cffi>=23.1.0",
|
||||||
"celery>=5.4.0",
|
"celery>=5.4.0",
|
||||||
"colorlog>=6.9.0",
|
"colorlog>=6.9.0",
|
||||||
"django-cors-headers>=4.6.0",
|
"django-cors-headers>=4.6.0",
|
||||||
@@ -13,6 +14,7 @@ dependencies = [
|
|||||||
"django-health-check>=3.18.3",
|
"django-health-check>=3.18.3",
|
||||||
"django-minio-storage>=0.5.7",
|
"django-minio-storage>=0.5.7",
|
||||||
"django-ninja>=1.3.0",
|
"django-ninja>=1.3.0",
|
||||||
|
"django-pagedown>=2.2.1",
|
||||||
"django-stubs-ext>=5.1.3",
|
"django-stubs-ext>=5.1.3",
|
||||||
"gunicorn>=23.0.0",
|
"gunicorn>=23.0.0",
|
||||||
"httpx>=0.28.1",
|
"httpx>=0.28.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user