Coverage for opt/mealie/lib/python3.12/site-packages/mealie/db/models/recipe/tag.py: 91%

32 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-11-25 15:48 +0000

1from typing import TYPE_CHECKING 1a

2 

3import sqlalchemy as sa 1a

4import sqlalchemy.orm as orm 1a

5from slugify import slugify 1a

6from sqlalchemy.orm import Mapped, mapped_column, validates 1a

7 

8from mealie.core import root_logger 1a

9from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase 1a

10from mealie.db.models._model_utils import guid 1a

11 

12if TYPE_CHECKING: 12 ↛ 13line 12 didn't jump to line 13 because the condition on line 12 was never true1a

13 from ..group import Group 

14 from . import RecipeModel 

15 

16 

17logger = root_logger.get_logger() 1a

18 

19recipes_to_tags = sa.Table( 1a

20 "recipes_to_tags", 

21 SqlAlchemyBase.metadata, 

22 sa.Column("recipe_id", guid.GUID, sa.ForeignKey("recipes.id"), index=True), 

23 sa.Column("tag_id", guid.GUID, sa.ForeignKey("tags.id"), index=True), 

24 sa.UniqueConstraint("recipe_id", "tag_id", name="recipe_id_tag_id_key"), 

25) 

26 

27plan_rules_to_tags = sa.Table( 1a

28 "plan_rules_to_tags", 

29 SqlAlchemyBase.metadata, 

30 sa.Column("plan_rule_id", guid.GUID, sa.ForeignKey("group_meal_plan_rules.id"), index=True), 

31 sa.Column("tag_id", guid.GUID, sa.ForeignKey("tags.id"), index=True), 

32 sa.UniqueConstraint("plan_rule_id", "tag_id", name="plan_rule_id_tag_id_key"), 

33) 

34 

35cookbooks_to_tags = sa.Table( 1a

36 "cookbooks_to_tags", 

37 SqlAlchemyBase.metadata, 

38 sa.Column("cookbook_id", guid.GUID, sa.ForeignKey("cookbooks.id"), index=True), 

39 sa.Column("tag_id", guid.GUID, sa.ForeignKey("tags.id"), index=True), 

40 sa.UniqueConstraint("cookbook_id", "tag_id", name="cookbook_id_tag_id_key"), 

41) 

42 

43 

44class Tag(SqlAlchemyBase, BaseMixins): 1a

45 __tablename__ = "tags" 1a

46 __table_args__ = (sa.UniqueConstraint("slug", "group_id", name="tags_slug_group_id_key"),) 1a

47 id: Mapped[guid.GUID] = mapped_column(guid.GUID, primary_key=True, default=guid.GUID.generate) 1a

48 

49 # ID Relationships 

50 group_id: Mapped[guid.GUID] = mapped_column(guid.GUID, sa.ForeignKey("groups.id"), nullable=False, index=True) 1a

51 group: Mapped["Group"] = orm.relationship("Group", back_populates="tags", foreign_keys=[group_id]) 1a

52 

53 name: Mapped[str] = mapped_column(sa.String, index=True, nullable=False) 1a

54 slug: Mapped[str] = mapped_column(sa.String, index=True, nullable=False) 1a

55 recipes: Mapped[list["RecipeModel"]] = orm.relationship( 1a

56 "RecipeModel", secondary=recipes_to_tags, back_populates="tags" 

57 ) 

58 

59 @validates("name") 1a

60 def validate_name(self, key, name): 1a

61 assert name != "" 

62 return name 

63 

64 def __init__(self, name, group_id, **_) -> None: 1a

65 self.group_id = group_id 

66 self.name = name.strip() 

67 self.slug = slugify(self.name)