mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-09 03:04:54 -04:00
fix: Pydantic Serialization Issues (#3157)
* replaced pydantic inits with validators * fixed serialization dropping food and unit ids
This commit is contained in:
parent
67313f8f03
commit
df75cb4034
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pydantic import UUID4, ConfigDict, field_validator
|
from pydantic import UUID4, ConfigDict, field_validator, model_validator
|
||||||
from sqlalchemy.orm import joinedload, selectinload
|
from sqlalchemy.orm import joinedload, selectinload
|
||||||
from sqlalchemy.orm.interfaces import LoaderOption
|
from sqlalchemy.orm.interfaces import LoaderOption
|
||||||
|
|
||||||
@ -100,14 +100,15 @@ class ShoppingListItemOut(ShoppingListItemBase):
|
|||||||
created_at: datetime | None = None
|
created_at: datetime | None = None
|
||||||
update_at: datetime | None = None
|
update_at: datetime | None = None
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
@model_validator(mode="after")
|
||||||
super().__init__(**kwargs)
|
def post_validate(self):
|
||||||
|
|
||||||
# if we're missing a label, but the food has a label, use that as the label
|
# if we're missing a label, but the food has a label, use that as the label
|
||||||
if (not self.label) and (self.food and self.food.label):
|
if (not self.label) and (self.food and self.food.label):
|
||||||
self.label = self.food.label
|
self.label = self.food.label
|
||||||
self.label_id = self.label.id
|
self.label_id = self.label.id
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
model_config = ConfigDict(from_attributes=True)
|
model_config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
from typing import Annotated, Any, ClassVar
|
from typing import Annotated, Any, ClassVar
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from pydantic import UUID4, BaseModel, ConfigDict, Field, field_validator
|
from pydantic import UUID4, BaseModel, ConfigDict, Field, field_validator, model_validator
|
||||||
from pydantic_core.core_schema import ValidationInfo
|
from pydantic_core.core_schema import ValidationInfo
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy import Select, desc, func, or_, select, text
|
from sqlalchemy import Select, desc, func, or_, select, text
|
||||||
@ -183,17 +183,8 @@ class Recipe(RecipeSummary):
|
|||||||
|
|
||||||
model_config = ConfigDict(from_attributes=True)
|
model_config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
@classmethod
|
@model_validator(mode="after")
|
||||||
def model_validate(cls, obj):
|
def post_validate(self):
|
||||||
recipe = super().model_validate(obj)
|
|
||||||
recipe.__post_init__()
|
|
||||||
return recipe
|
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
self.__post_init__()
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
# the ingredient disable_amount property is unreliable,
|
# the ingredient disable_amount property is unreliable,
|
||||||
# so we set it here and recalculate the display property
|
# so we set it here and recalculate the display property
|
||||||
disable_amount = self.settings.disable_amount if self.settings else True
|
disable_amount = self.settings.disable_amount if self.settings else True
|
||||||
@ -202,6 +193,8 @@ class Recipe(RecipeSummary):
|
|||||||
ingredient.is_food = not ingredient.disable_amount
|
ingredient.is_food = not ingredient.disable_amount
|
||||||
ingredient.display = ingredient._format_display()
|
ingredient.display = ingredient._format_display()
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
@field_validator("slug", mode="before")
|
@field_validator("slug", mode="before")
|
||||||
def validate_slug(slug: str, info: ValidationInfo):
|
def validate_slug(slug: str, info: ValidationInfo):
|
||||||
if not info.data.get("name"):
|
if not info.data.get("name"):
|
||||||
|
@ -6,7 +6,7 @@ from fractions import Fraction
|
|||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
from pydantic import UUID4, ConfigDict, Field, field_validator
|
from pydantic import UUID4, ConfigDict, Field, field_validator, model_validator
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
from sqlalchemy.orm.interfaces import LoaderOption
|
from sqlalchemy.orm.interfaces import LoaderOption
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ def display_fraction(fraction: Fraction):
|
|||||||
|
|
||||||
|
|
||||||
class UnitFoodBase(MealieModel):
|
class UnitFoodBase(MealieModel):
|
||||||
|
id: UUID4 | None = None
|
||||||
name: str
|
name: str
|
||||||
plural_name: str | None = None
|
plural_name: str | None = None
|
||||||
description: str = ""
|
description: str = ""
|
||||||
@ -134,9 +135,8 @@ class RecipeIngredientBase(MealieModel):
|
|||||||
Automatically calculated after the object is created, unless overwritten
|
Automatically calculated after the object is created, unless overwritten
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
@model_validator(mode="after")
|
||||||
super().__init__(**kwargs)
|
def post_validate(self):
|
||||||
|
|
||||||
# calculate missing is_food and disable_amount values
|
# calculate missing is_food and disable_amount values
|
||||||
# we can't do this in a validator since they depend on each other
|
# we can't do this in a validator since they depend on each other
|
||||||
if self.is_food is None and self.disable_amount is not None:
|
if self.is_food is None and self.disable_amount is not None:
|
||||||
@ -151,6 +151,8 @@ class RecipeIngredientBase(MealieModel):
|
|||||||
if not self.display:
|
if not self.display:
|
||||||
self.display = self._format_display()
|
self.display = self._format_display()
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
@field_validator("unit", mode="before")
|
@field_validator("unit", mode="before")
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_unit(cls, v):
|
def validate_unit(cls, v):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user