Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/models/agreement.py: 54%
31 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
4from __future__ import annotations
6from typing import TYPE_CHECKING
8from django.conf import settings
9from django.db import models
11if TYPE_CHECKING: 11 ↛ 12line 11 didn't jump to line 12 because the condition on line 11 was never true
12 from weblate.auth.models import User
13 from weblate.trans.models import Component
16class ContributorAgreementManager(models.Manager):
17 def has_agreed(self, user: User, component: Component):
18 if user.is_anonymous:
19 return False
20 cache_key = (user.pk, component.pk)
21 if cache_key not in user.cla_cache:
22 user.cla_cache[cache_key] = self.filter(
23 component=component, user=user
24 ).exists()
25 return user.cla_cache[cache_key]
27 def create(self, user: User, component: Component, **kwargs):
28 user.cla_cache[user.pk, component.pk] = True
29 return super().create(user=user, component=component, **kwargs)
31 def order(self):
32 return self.order_by("component__project__name", "component__name")
35class ContributorAgreement(models.Model):
36 user = models.ForeignKey(
37 settings.AUTH_USER_MODEL, on_delete=models.deletion.CASCADE, db_index=False
38 )
39 component = models.ForeignKey("trans.Component", on_delete=models.deletion.CASCADE)
40 timestamp = models.DateTimeField(auto_now=True)
42 objects = ContributorAgreementManager()
44 class Meta:
45 unique_together = [("user", "component")] # noqa: RUF012
46 verbose_name = "contributor license agreement"
47 verbose_name_plural = "contributor license agreements"
49 def __str__(self) -> str:
50 return f"{self.user.username}:{self.component}"