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
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:48 +0000
1from typing import TYPE_CHECKING 1a
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
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
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
17logger = root_logger.get_logger() 1a
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)
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)
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)
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
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
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 )
59 @validates("name") 1a
60 def validate_name(self, key, name): 1a
61 assert name != ""
62 return name
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)