Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/contrib/postgres/forms/ranges.py: 52%

62 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange 

2 

3from django import forms 

4from django.core import exceptions 

5from django.forms.widgets import HiddenInput, MultiWidget 

6from django.utils.translation import gettext_lazy as _ 

7 

8__all__ = [ 

9 "BaseRangeField", 

10 "IntegerRangeField", 

11 "DecimalRangeField", 

12 "DateTimeRangeField", 

13 "DateRangeField", 

14 "HiddenRangeWidget", 

15 "RangeWidget", 

16] 

17 

18 

19class RangeWidget(MultiWidget): 

20 def __init__(self, base_widget, attrs=None): 

21 widgets = (base_widget, base_widget) 

22 super().__init__(widgets, attrs) 

23 

24 def decompress(self, value): 

25 if value: 

26 return (value.lower, value.upper) 

27 return (None, None) 

28 

29 

30class HiddenRangeWidget(RangeWidget): 

31 """A widget that splits input into two <input type="hidden"> inputs.""" 

32 

33 def __init__(self, attrs=None): 

34 super().__init__(HiddenInput, attrs) 

35 

36 

37class BaseRangeField(forms.MultiValueField): 

38 default_error_messages = { 

39 "invalid": _("Enter two valid values."), 

40 "bound_ordering": _( 

41 "The start of the range must not exceed the end of the range." 

42 ), 

43 } 

44 hidden_widget = HiddenRangeWidget 

45 

46 def __init__(self, **kwargs): 

47 if "widget" not in kwargs: 

48 kwargs["widget"] = RangeWidget(self.base_field.widget) 

49 if "fields" not in kwargs: 

50 kwargs["fields"] = [ 

51 self.base_field(required=False), 

52 self.base_field(required=False), 

53 ] 

54 kwargs.setdefault("required", False) 

55 kwargs.setdefault("require_all_fields", False) 

56 super().__init__(**kwargs) 

57 

58 def prepare_value(self, value): 

59 lower_base, upper_base = self.fields 

60 if isinstance(value, self.range_type): 

61 return [ 

62 lower_base.prepare_value(value.lower), 

63 upper_base.prepare_value(value.upper), 

64 ] 

65 if value is None: 

66 return [ 

67 lower_base.prepare_value(None), 

68 upper_base.prepare_value(None), 

69 ] 

70 return value 

71 

72 def compress(self, values): 

73 if not values: 

74 return None 

75 lower, upper = values 

76 if lower is not None and upper is not None and lower > upper: 

77 raise exceptions.ValidationError( 

78 self.error_messages["bound_ordering"], 

79 code="bound_ordering", 

80 ) 

81 try: 

82 range_value = self.range_type(lower, upper) 

83 except TypeError: 

84 raise exceptions.ValidationError( 

85 self.error_messages["invalid"], 

86 code="invalid", 

87 ) 

88 else: 

89 return range_value 

90 

91 

92class IntegerRangeField(BaseRangeField): 

93 default_error_messages = {"invalid": _("Enter two whole numbers.")} 

94 base_field = forms.IntegerField 

95 range_type = NumericRange 

96 

97 

98class DecimalRangeField(BaseRangeField): 

99 default_error_messages = {"invalid": _("Enter two numbers.")} 

100 base_field = forms.DecimalField 

101 range_type = NumericRange 

102 

103 

104class DateTimeRangeField(BaseRangeField): 

105 default_error_messages = {"invalid": _("Enter two valid date/times.")} 

106 base_field = forms.DateTimeField 

107 range_type = DateTimeTZRange 

108 

109 

110class DateRangeField(BaseRangeField): 

111 default_error_messages = {"invalid": _("Enter two valid dates.")} 

112 base_field = forms.DateField 

113 range_type = DateRange