• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

akvo / akvo-mis / #774

30 Jul 2026 07:05AM UTC coverage: 88.786% (+0.3%) from 88.523%
#774

push

coveralls-python

web-flow
Merge ef7087147 into ca88641e4

5733 of 6629 branches covered (86.48%)

Branch coverage included in aggregate %.

10877 of 12079 relevant lines covered (90.05%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.87
backend/utils/draft_model.py
1
from django.db import models
1✔
2
from .soft_deletes_model import SoftDeletesQuerySet, SoftDeletesManager
1✔
3
from .tenant_scoped_model import TenantScopedQuerySetMixin
1✔
4

5

6
class DraftQuerySet(TenantScopedQuerySetMixin, models.QuerySet):
1✔
7
    def only_draft(self):
1✔
8
        return self.filter(is_draft=True)
×
9

10
    def without_draft(self):
1✔
11
        return self.filter(is_draft=False)
×
12

13
    def published(self):
1✔
14
        return self.filter(is_draft=False)
×
15

16

17
class DraftSoftDeletesQuerySet(SoftDeletesQuerySet):
1✔
18
    def only_draft(self):
1✔
19
        return self.filter(is_draft=True)
1✔
20

21
    def without_draft(self):
1✔
22
        return self.filter(is_draft=False)
×
23

24
    def published(self):
1✔
25
        return self.filter(is_draft=False)
×
26

27

28
class DraftManager(models.Manager):
1✔
29
    def __init__(self, *args, **kwargs):
1✔
30
        self.only_draft = kwargs.pop("only_draft", False)
1✔
31
        super().__init__(*args, **kwargs)
1✔
32

33
    def get_queryset(self):
1✔
34
        if self.only_draft:
×
35
            return DraftQuerySet(self.model).only_draft()
×
36
        return DraftQuerySet(self.model).without_draft()
×
37

38
    def published(self):
1✔
39
        return self.get_queryset().published()
×
40

41
    def draft(self):
1✔
42
        return DraftQuerySet(self.model).only_draft()
×
43

44
    def for_user(self, user):
1✔
45
        return self.get_queryset().for_user(user)
×
46

47

48
class DraftSoftDeletesManager(SoftDeletesManager):
1✔
49
    def __init__(self, *args, **kwargs):
1✔
50
        self.only_draft = kwargs.pop("only_draft", False)
1✔
51
        super().__init__(*args, **kwargs)
1✔
52

53
    def get_queryset(self):
1✔
54
        if self.only_draft:
1✔
55
            # For draft data, we only care about non-deleted drafts
56
            # since drafts are always hard deleted
57
            queryset = DraftSoftDeletesQuerySet(self.model)
1✔
58
            return queryset.without_deleted().only_draft()
1✔
59
        # For non-draft queries, use the parent logic
60
        return super().get_queryset()
1✔
61

62
    def draft(self):
1✔
63
        queryset = DraftSoftDeletesQuerySet(self.model)
×
64
        return queryset.without_deleted().only_draft()
×
65

66

67
class Draft(models.Model):
1✔
68
    is_draft = models.BooleanField(default=False)
1✔
69

70
    class Meta:
1✔
71
        abstract = True
1✔
72

73
    objects = DraftManager()
1✔
74
    objects_draft = DraftManager(only_draft=True)
1✔
75

76
    def publish(self) -> None:
1✔
77
        self.is_draft = False
1✔
78
        self.save(update_fields=["is_draft"])
1✔
79

80
    def mark_as_draft(self) -> None:
1✔
81
        self.is_draft = True
1✔
82
        self.save(update_fields=["is_draft"])
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc