Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/models/componentlist.py: 72%
48 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
5"""Components list."""
7from __future__ import annotations
9import re
10from typing import TYPE_CHECKING
12from django.db import models
13from django.urls import reverse
14from django.utils.translation import gettext_lazy
16from weblate.trans.fields import RegexField
17from weblate.trans.mixins import CacheKeyMixin
18from weblate.utils.stats import ComponentListStats
20if TYPE_CHECKING: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true
21 from weblate.trans.models.translation import Translation
24class ComponentListQuerySet(models.QuerySet):
25 def order(self):
26 return self.order_by("name")
29class ComponentList(models.Model, CacheKeyMixin):
30 name = models.CharField(
31 verbose_name=gettext_lazy("Component list name"),
32 max_length=100,
33 unique=True,
34 help_text=gettext_lazy("Display name"),
35 )
37 slug = models.SlugField(
38 verbose_name=gettext_lazy("URL slug"),
39 db_index=True,
40 unique=True,
41 max_length=100,
42 help_text=gettext_lazy("Name used in URLs and filenames."),
43 )
44 show_dashboard = models.BooleanField(
45 verbose_name=gettext_lazy("Show on dashboard"),
46 default=True,
47 db_index=True,
48 help_text=gettext_lazy(
49 "When enabled this component list will be shown as a tab on the dashboard"
50 ),
51 )
53 components = models.ManyToManyField("trans.Component", blank=True)
55 # Used on dashboard
56 translations: list[Translation]
58 objects = ComponentListQuerySet.as_manager()
60 class Meta:
61 verbose_name = "Component list"
62 verbose_name_plural = "Component lists"
64 def __str__(self) -> str:
65 return self.name
67 def __init__(self, *args, **kwargs) -> None:
68 super().__init__(*args, **kwargs)
69 self.stats = ComponentListStats(self)
71 def get_absolute_url(self) -> str:
72 return reverse("component-list", kwargs={"name": self.slug})
74 def tab_slug(self):
75 return "list-" + self.slug
78class AutoComponentList(models.Model):
79 project_match = RegexField(
80 verbose_name=gettext_lazy("Project regular expression"),
81 max_length=200,
82 default="^$",
83 help_text=gettext_lazy(
84 "Regular expression which is used to match project slug."
85 ),
86 )
87 component_match = RegexField(
88 verbose_name=gettext_lazy("Component regular expression"),
89 max_length=200,
90 default="^$",
91 help_text=gettext_lazy(
92 "Regular expression which is used to match component slug."
93 ),
94 )
95 componentlist = models.ForeignKey(
96 ComponentList,
97 verbose_name=gettext_lazy("Component list to assign"),
98 on_delete=models.deletion.CASCADE,
99 )
101 class Meta:
102 verbose_name = "Automatic component list assignment"
103 verbose_name_plural = "Automatic component list assignments"
105 def __str__(self) -> str:
106 return self.componentlist.name
108 def check_match(self, component) -> None:
109 if not re.match(self.project_match, component.project.slug):
110 return
111 if not re.match(self.component_match, component.slug):
112 return
113 self.componentlist.components.add(component)