Coverage for src/paperap/models/mixins/queryset.py: 64%
25 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-18 12:26 -0400
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-18 12:26 -0400
1"""
2----------------------------------------------------------------------------
4 METADATA:
6 File: queryset.py
7 Project: paperap
8 Created: 2025-03-05
9 Version: 0.0.5
10 Author: Jess Mann
11 Email: jess@jmann.me
12 Copyright (c) 2025 Jess Mann
14----------------------------------------------------------------------------
16 LAST MODIFIED:
18 2025-03-05 By Jess Mann
20"""
22from __future__ import annotations
24from typing import TYPE_CHECKING, Any, Protocol, Self
26if TYPE_CHECKING:
27 from paperap.models.abstract.queryset import BaseQuerySet, StandardQuerySet
30class QuerySetProtocol(Protocol):
31 """
32 Protocol for querysets.
34 Used primarily for type hinting.
35 """
37 def all(self) -> Self: ... # pylint: disable=missing-function-docstring
38 def filter(self, **kwargs: Any) -> Self: ... # pylint: disable=missing-function-docstring
39 def filter_field_by_str( # pylint: disable=missing-function-docstring
40 self, field: str, value: str, *, exact: bool = True, case_insensitive: bool = True
41 ) -> Self: ...
44class HasDocumentCount(QuerySetProtocol):
45 """
46 Mixin for querysets that have a document_count field.
47 """
49 def document_count(self, count: int) -> Self:
50 """
51 Filter models by document count.
53 Args:
54 count: The document count to filter by
56 Returns:
57 Filtered QuerySet
59 """
60 return self.filter(document_count=count)
62 def document_count_over(self, count: int) -> Self:
63 """
64 Filter models by document count greater than a value.
66 Args:
67 count: The document count to filter by
69 Returns:
70 Filtered QuerySet
72 """
73 return self.filter(document_count__gt=count)
75 def document_count_under(self, count: int) -> Self:
76 """
77 Filter models by document count less than a value.
79 Args:
80 count: The document count to filter by
82 Returns:
83 Filtered QuerySet
85 """
86 return self.filter(document_count__lt=count)
88 def document_count_between(self, lower: int, upper: int) -> Self:
89 """
90 Filter models by document count between two values.
92 Args:
93 lower: The lower document count to filter by
94 upper: The upper document count to filter by
96 Returns:
97 Filtered QuerySet
99 """
100 return self.filter(document_count__range=(lower, upper))
103class HasOwner(QuerySetProtocol):
104 """
105 Mixin for querysets that have an owner field.
106 """
108 def owner(self, owner: int | list[int] | None) -> Self:
109 """
110 Filter models by owner.
112 Args:
113 owner: The owner to filter by
115 Returns:
116 Filtered QuerySet
118 """
119 if isinstance(owner, list):
120 return self.filter(owner__in=owner)
121 return self.filter(owner=owner)
124class HasStandard(HasOwner, HasDocumentCount):
125 """
126 Mixin for querysets that have standard fields: owner, document_count, name, slug
127 """
129 def name(self, value: str, *, exact: bool = True, case_insensitive: bool = True) -> Self:
130 """
131 Filter models where name is value
133 Args:
134 value (str): The value to compare against
135 exact (bool): Whether the comparison should be exact
136 case_sensitive (bool): Whether the comparison should be case insensitive
138 Returns:
139 Filtered QuerySet
141 """
142 return self.filter_field_by_str("name", value, exact=exact, case_insensitive=case_insensitive)
144 def slug(self, value: str, *, exact: bool = True, case_insensitive: bool = True) -> Self:
145 """
146 Filter models where slug is value
148 Args:
149 value (str): The value to compare against
150 exact (bool): Whether the comparison should be exact
151 case_sensitive (bool): Whether the comparison should be case insensitive
153 Returns:
154 Filtered QuerySet
156 """
157 return self.filter_field_by_str("slug", value, exact=exact, case_insensitive=case_insensitive)