formaptix-server/models/form.py

109 lines
2.8 KiB
Python
Raw Normal View History

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-14 16:21:23 +03:00
from uuid import UUID, uuid4
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):
2024-08-14 16:21:23 +03:00
id: UUID = Field(default_factory=uuid4)
2024-08-10 20:38:54 +03:00
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-14 16:21:23 +03:00
@field_validator("questions")
@classmethod
def validate_questions(
cls,
v,
info
):
questions = info.data.get("questions")
uuids = set()
for question in questions:
uuids.add(question.question_id)
if len(questions) != len(uuids):
raise ValueError(
"All questions must have different id's"
)
return v
2024-08-12 16:57:40 +03:00
2024-08-11 16:45:17 +03:00
class Form(BaseModel):
id: int
2024-08-12 16:57:40 +03:00
data: FormData