2024-08-12 16:57:40 +03:00
|
|
|
from enum import IntEnum, auto
|
2024-08-11 16:45:17 +03:00
|
|
|
from typing import TypeAlias
|
2024-08-10 20:38:54 +03:00
|
|
|
|
2024-08-11 16:45:17 +03:00
|
|
|
from pydantic import Field, field_validator
|
2024-08-10 20:38:54 +03:00
|
|
|
|
|
|
|
from models import BaseModel
|
|
|
|
|
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
class QuestionType(IntEnum):
|
|
|
|
text = 1
|
|
|
|
selector = 2
|
2024-08-10 20:38:54 +03:00
|
|
|
|
|
|
|
|
|
|
|
class BaseQuestion(BaseModel):
|
|
|
|
question_type: QuestionType
|
|
|
|
label: str = Field(min_length=1)
|
|
|
|
description: str | None = Field(None, min_length=1)
|
2024-08-11 16:45:17 +03:00
|
|
|
required: bool = True
|
|
|
|
|
|
|
|
|
|
|
|
class Option(BaseModel):
|
|
|
|
label: str
|
2024-08-10 20:38:54 +03:00
|
|
|
|
|
|
|
|
|
|
|
class TextQuestion(BaseQuestion):
|
2024-08-12 16:57:40 +03:00
|
|
|
question_type: QuestionType = QuestionType.text
|
2024-08-10 20:38:54 +03:00
|
|
|
min_length: int | None = None
|
|
|
|
max_length: int | None = None
|
2024-08-11 16:45:17 +03:00
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
@field_validator("min_length")
|
2024-08-11 16:45:17 +03:00
|
|
|
@classmethod
|
2024-08-12 16:57:40 +03:00
|
|
|
def validate_min_length(cls, v, info):
|
2024-08-11 16:45:17 +03:00
|
|
|
if v is not None and v < 0:
|
2024-08-12 16:57:40 +03:00
|
|
|
raise ValueError("min_length must be greater than or equal to 0")
|
2024-08-11 16:45:17 +03:00
|
|
|
return v
|
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
@field_validator("max_length")
|
2024-08-11 16:45:17 +03:00
|
|
|
@classmethod
|
2024-08-12 16:57:40 +03:00
|
|
|
def validate_max_length(cls, v, info):
|
|
|
|
min_length = info.data.get("min_length")
|
2024-08-11 16:45:17 +03:00
|
|
|
if v is not None:
|
|
|
|
if v <= 0:
|
2024-08-12 16:57:40 +03:00
|
|
|
raise ValueError("max_length must be greater than 0")
|
2024-08-11 16:45:17 +03:00
|
|
|
if min_length is not None and v < min_length:
|
2024-08-12 16:57:40 +03:00
|
|
|
raise ValueError("max_length cannot be less than min_length")
|
2024-08-11 16:45:17 +03:00
|
|
|
return v
|
|
|
|
|
|
|
|
|
|
|
|
class SelectorQuestion(BaseQuestion):
|
2024-08-12 16:57:40 +03:00
|
|
|
question_type: QuestionType = QuestionType.selector
|
2024-08-11 16:45:17 +03:00
|
|
|
min_values: int = 1
|
|
|
|
max_values: int | None = None
|
|
|
|
options: list[Option] = []
|
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
@field_validator("min_values")
|
2024-08-11 16:45:17 +03:00
|
|
|
@classmethod
|
2024-08-12 16:57:40 +03:00
|
|
|
def validate_min_values(cls, v, info):
|
|
|
|
options = info.data.get("options")
|
2024-08-11 16:45:17 +03:00
|
|
|
if v is not None and (v < 1 or v > len(options)):
|
2024-08-12 16:57:40 +03:00
|
|
|
raise ValueError("min_values must be greater than or equal to 1")
|
2024-08-11 16:45:17 +03:00
|
|
|
return v
|
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
@field_validator("max_values")
|
2024-08-11 16:45:17 +03:00
|
|
|
@classmethod
|
2024-08-12 16:57:40 +03:00
|
|
|
def validate_max_values(cls, v, info):
|
|
|
|
min_values = info.data.get("min_values")
|
|
|
|
options = info.data.get("options")
|
2024-08-11 16:45:17 +03:00
|
|
|
if v is not None and (v > len(options) or min_values > v):
|
2024-08-12 16:57:40 +03:00
|
|
|
raise ValueError(
|
|
|
|
"max_values cannot be less than min_length or greater than the number of options"
|
|
|
|
)
|
2024-08-11 16:45:17 +03:00
|
|
|
return v
|
|
|
|
|
|
|
|
|
|
|
|
Question: TypeAlias = SelectorQuestion | TextQuestion
|
|
|
|
|
|
|
|
|
2024-08-12 16:57:40 +03:00
|
|
|
class FormData(BaseModel):
|
|
|
|
name: str = Field(min_length=1)
|
|
|
|
description: str | None = Field(None, min_length=1)
|
|
|
|
questions: list[Question] = []
|
|
|
|
|
|
|
|
|
2024-08-11 16:45:17 +03:00
|
|
|
class Form(BaseModel):
|
|
|
|
id: int
|
2024-08-12 16:57:40 +03:00
|
|
|
data: FormData
|